From lattner at cs.uiuc.edu Mon Sep 26 00:14:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 00:14:59 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll Message-ID: <200509260514.AAA08204@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/GlobalOpt: ctor-list-opt.ll updated: 1.3 -> 1.4 --- Log message: add a test for load --- Diffs of the changes: (+10 -1) ctor-list-opt.ll | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletion(-) Index: llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll diff -u llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.3 llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.4 --- llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.3 Sun Sep 25 23:57:10 2005 +++ llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll Mon Sep 26 00:14:48 2005 @@ -1,16 +1,18 @@ ; RUN: llvm-as < %s | opt -globalopt -disable-output && ; RUN: llvm-as < %s | opt -globalopt | llvm-dis | not grep CTOR -%llvm.global_ctors = appending global [5 x { int, void ()* }] [ +%llvm.global_ctors = appending global [6 x { int, void ()* }] [ { int, void ()* } { int 65535, void ()* %CTOR1 }, { int, void ()* } { int 65535, void ()* %CTOR1 }, { int, void ()* } { int 65535, void ()* %CTOR2 }, { int, void ()* } { int 65535, void ()* %CTOR3 }, + { int, void ()* } { int 65535, void ()* %CTOR4 }, { int, void ()* } { int 2147483647, void ()* null } ] %G = global int 0 %G2 = global int 0 +%G3 = global int -123 %CTORGV = internal global bool false ;; Should become constant after eval @@ -39,6 +41,13 @@ ret void } +internal void %CTOR4() { + %X = load int* %G3 + %Y = add int %X, 123 + store int %Y, int* %G3 + ret void +} + bool %accessor() { %V = load bool* %CTORGV ;; constant true ret bool %V From lattner at cs.uiuc.edu Mon Sep 26 00:15:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 00:15:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200509260515.AAA08267@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.46 -> 1.47 --- Log message: Add support for getelementptr, load, and correctly reject volatile stores. --- Diffs of the changes: (+29 -0) GlobalOpt.cpp | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.46 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.47 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.46 Sun Sep 25 23:57:38 2005 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 26 00:15:37 2005 @@ -1263,6 +1263,23 @@ GV->setInitializer(Val); } +static Constant *ComputeLoadResult(Constant *P, + const std::map &Memory) { + // If this memory location has been recently stored, use the stored value: it + // is the most up-to-date. + std::map::const_iterator I = Memory.find(P); + if (I != Memory.end()) return I->second; + + // Access it. + if (GlobalVariable *GV = dyn_cast(P)) { + if (GV->hasInitializer()) + return GV->getInitializer(); + return 0; + } else { + return 0; // don't know how to evaluate. + } +} + /// EvaluateStaticConstructor - Evaluate static constructors in the function, if /// we can. Return true if we can, false otherwise. static bool EvaluateStaticConstructor(Function *F) { @@ -1288,6 +1305,7 @@ Constant *InstResult = 0; if (StoreInst *SI = dyn_cast(CurInst)) { + if (SI->isVolatile()) return false; // no volatile accesses. Constant *Ptr = getVal(Values, SI->getOperand(1)); if (!isSimpleEnoughPointerToCommit(Ptr)) // If this is too complex for us to commit, reject it. @@ -1309,6 +1327,17 @@ InstResult = ConstantExpr::getSelect(getVal(Values, SI->getOperand(0)), getVal(Values, SI->getOperand(1)), getVal(Values, SI->getOperand(2))); + } else if (GetElementPtrInst *GEP = dyn_cast(CurInst)) { + Constant *P = getVal(Values, GEP->getOperand(0)); + std::vector GEPOps; + for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i) + GEPOps.push_back(getVal(Values, GEP->getOperand(i))); + InstResult = ConstantExpr::getGetElementPtr(P, GEPOps); + } else if (LoadInst *LI = dyn_cast(CurInst)) { + if (LI->isVolatile()) return false; // no volatile accesses. + InstResult = ComputeLoadResult(getVal(Values, LI->getOperand(0)), + MutatedMemory); + if (InstResult == 0) return false; // Could not evaluate load. } else if (TerminatorInst *TI = dyn_cast(CurInst)) { BasicBlock *NewBB = 0; if (BranchInst *BI = dyn_cast(CurInst)) { From lattner at cs.uiuc.edu Mon Sep 26 00:16:46 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 00:16:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200509260516.AAA08328@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.47 -> 1.48 --- Log message: add a comment --- Diffs of the changes: (+3 -0) GlobalOpt.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.47 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.48 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.47 Mon Sep 26 00:15:37 2005 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 26 00:16:34 2005 @@ -1263,6 +1263,9 @@ GV->setInitializer(Val); } +/// ComputeLoadResult - Return the value that would be computed by a load from +/// P after the stores reflected by 'memory' have been performed. If we can't +/// decide, return null. static Constant *ComputeLoadResult(Constant *P, const std::map &Memory) { // If this memory location has been recently stored, use the stored value: it From lattner at cs.uiuc.edu Mon Sep 26 00:26:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 00:26:43 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/Local.h Message-ID: <200509260526.AAA08403@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: Local.h updated: 1.19 -> 1.20 --- Log message: add a new function --- Diffs of the changes: (+5 -0) Local.h | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/include/llvm/Transforms/Utils/Local.h diff -u llvm/include/llvm/Transforms/Utils/Local.h:1.19 llvm/include/llvm/Transforms/Utils/Local.h:1.20 --- llvm/include/llvm/Transforms/Utils/Local.h:1.19 Thu Aug 4 18:24:19 2005 +++ llvm/include/llvm/Transforms/Utils/Local.h Mon Sep 26 00:26:32 2005 @@ -22,6 +22,7 @@ class Pass; class PHINode; class AllocaInst; +class ConstantExpr; //===----------------------------------------------------------------------===// // Local constant propagation... @@ -55,6 +56,10 @@ /// with the specified arguments, returning null if unsuccessful. Constant *ConstantFoldCall(Function *F, const std::vector &Operands); +/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a +/// getelementptr constantexpr, return the constant value being addressed by the +/// constant expression, or null if something is funny and we can't decide. +Constant *ConstantFoldLoadThroughGEPConstantExpr(Constant *C, ConstantExpr *CE); //===----------------------------------------------------------------------===// // Local dead code elimination... From lattner at cs.uiuc.edu Mon Sep 26 00:27:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 00:27:21 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Local.cpp Message-ID: <200509260527.AAA08483@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Local.cpp updated: 1.42 -> 1.43 --- Log message: Move the ConstantFoldLoadThroughGEPConstantExpr function out of the InstCombine pass. --- Diffs of the changes: (+45 -1) Local.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 45 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/Utils/Local.cpp diff -u llvm/lib/Transforms/Utils/Local.cpp:1.42 llvm/lib/Transforms/Utils/Local.cpp:1.43 --- llvm/lib/Transforms/Utils/Local.cpp:1.42 Thu Aug 4 18:24:19 2005 +++ llvm/lib/Transforms/Utils/Local.cpp Mon Sep 26 00:27:10 2005 @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Support/MathExtras.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" +#include "llvm/Support/MathExtras.h" #include #include using namespace llvm; @@ -366,6 +368,48 @@ } +/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a +/// getelementptr constantexpr, return the constant value being addressed by the +/// constant expression, or null if something is funny and we can't decide. +Constant *llvm::ConstantFoldLoadThroughGEPConstantExpr(Constant *C, + ConstantExpr *CE) { + if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType())) + return 0; // Do not allow stepping over the value! + + // Loop over all of the operands, tracking down which value we are + // addressing... + gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE); + for (++I; I != E; ++I) + if (const StructType *STy = dyn_cast(*I)) { + ConstantUInt *CU = cast(I.getOperand()); + assert(CU->getValue() < STy->getNumElements() && + "Struct index out of range!"); + unsigned El = (unsigned)CU->getValue(); + if (ConstantStruct *CS = dyn_cast(C)) { + C = CS->getOperand(El); + } else if (isa(C)) { + C = Constant::getNullValue(STy->getElementType(El)); + } else if (isa(C)) { + C = UndefValue::get(STy->getElementType(El)); + } else { + return 0; + } + } else if (ConstantInt *CI = dyn_cast(I.getOperand())) { + const ArrayType *ATy = cast(*I); + if ((uint64_t)CI->getRawValue() >= ATy->getNumElements()) return 0; + if (ConstantArray *CA = dyn_cast(C)) + C = CA->getOperand((unsigned)CI->getRawValue()); + else if (isa(C)) + C = Constant::getNullValue(ATy->getElementType()); + else if (isa(C)) + C = UndefValue::get(ATy->getElementType()); + else + return 0; + } else { + return 0; + } + return C; +} //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Mon Sep 26 00:28:18 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 00:28:18 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200509260528.AAA08518@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.381 -> 1.382 --- Log message: Factor the GetGEPGlobalInitializer out of this pass and into Transforms/Utils as ConstantFoldLoadThroughGEPConstantExpr. --- Diffs of the changes: (+2 -44) InstructionCombining.cpp | 46 ++-------------------------------------------- 1 files changed, 2 insertions(+), 44 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.381 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.382 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.381 Sat Sep 24 18:43:33 2005 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Sep 26 00:28:06 2005 @@ -5149,49 +5149,6 @@ } -/// GetGEPGlobalInitializer - Given a constant, and a getelementptr -/// constantexpr, return the constant value being addressed by the constant -/// expression, or null if something is funny. -/// -static Constant *GetGEPGlobalInitializer(Constant *C, ConstantExpr *CE) { - if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType())) - return 0; // Do not allow stepping over the value! - - // Loop over all of the operands, tracking down which value we are - // addressing... - gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE); - for (++I; I != E; ++I) - if (const StructType *STy = dyn_cast(*I)) { - ConstantUInt *CU = cast(I.getOperand()); - assert(CU->getValue() < STy->getNumElements() && - "Struct index out of range!"); - unsigned El = (unsigned)CU->getValue(); - if (ConstantStruct *CS = dyn_cast(C)) { - C = CS->getOperand(El); - } else if (isa(C)) { - C = Constant::getNullValue(STy->getElementType(El)); - } else if (isa(C)) { - C = UndefValue::get(STy->getElementType(El)); - } else { - return 0; - } - } else if (ConstantInt *CI = dyn_cast(I.getOperand())) { - const ArrayType *ATy = cast(*I); - if ((uint64_t)CI->getRawValue() >= ATy->getNumElements()) return 0; - if (ConstantArray *CA = dyn_cast(C)) - C = CA->getOperand((unsigned)CI->getRawValue()); - else if (isa(C)) - C = Constant::getNullValue(ATy->getElementType()); - else if (isa(C)) - C = UndefValue::get(ATy->getElementType()); - else - return 0; - } else { - return 0; - } - return C; -} - /// InstCombineLoadCast - Fold 'load (cast P)' -> cast (load P)' when possible. static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI) { User *CI = cast(LI.getOperand(0)); @@ -5318,7 +5275,8 @@ if (CE->getOpcode() == Instruction::GetElementPtr) { if (GlobalVariable *GV = dyn_cast(CE->getOperand(0))) if (GV->isConstant() && !GV->isExternal()) - if (Constant *V = GetGEPGlobalInitializer(GV->getInitializer(), CE)) + if (Constant *V = + ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE)) return ReplaceInstUsesWith(LI, V); if (CE->getOperand(0)->isNullValue()) { // Insert a new store to null instruction before the load to indicate From lattner at cs.uiuc.edu Mon Sep 26 00:29:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 00:29:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200509260529.AAA08575@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: SCCP.cpp updated: 1.124 -> 1.125 --- Log message: Eliminate GetGEPGlobalInitializer in favor of the more powerful ConstantFoldLoadThroughGEPConstantExpr function in the utils lib. --- Diffs of the changes: (+1 -27) SCCP.cpp | 28 +--------------------------- 1 files changed, 1 insertion(+), 27 deletions(-) Index: llvm/lib/Transforms/Scalar/SCCP.cpp diff -u llvm/lib/Transforms/Scalar/SCCP.cpp:1.124 llvm/lib/Transforms/Scalar/SCCP.cpp:1.125 --- llvm/lib/Transforms/Scalar/SCCP.cpp:1.124 Sat Apr 23 16:38:35 2005 +++ llvm/lib/Transforms/Scalar/SCCP.cpp Mon Sep 26 00:28:52 2005 @@ -756,32 +756,6 @@ markConstant(IV, &I, ConstantExpr::getGetElementPtr(Ptr, Operands)); } -/// GetGEPGlobalInitializer - Given a constant and a getelementptr constantexpr, -/// return the constant value being addressed by the constant expression, or -/// null if something is funny. -/// -static Constant *GetGEPGlobalInitializer(Constant *C, ConstantExpr *CE) { - if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType())) - return 0; // Do not allow stepping over the value! - - // Loop over all of the operands, tracking down which value we are - // addressing... - for (unsigned i = 2, e = CE->getNumOperands(); i != e; ++i) - if (ConstantUInt *CU = dyn_cast(CE->getOperand(i))) { - ConstantStruct *CS = dyn_cast(C); - if (CS == 0) return 0; - if (CU->getValue() >= CS->getNumOperands()) return 0; - C = CS->getOperand((unsigned)CU->getValue()); - } else if (ConstantSInt *CS = dyn_cast(CE->getOperand(i))) { - ConstantArray *CA = dyn_cast(C); - if (CA == 0) return 0; - if ((uint64_t)CS->getValue() >= CA->getNumOperands()) return 0; - C = CA->getOperand((unsigned)CS->getValue()); - } else - return 0; - return C; -} - void SCCPSolver::visitStoreInst(Instruction &SI) { if (TrackedGlobals.empty() || !isa(SI.getOperand(1))) return; @@ -838,7 +812,7 @@ if (GlobalVariable *GV = dyn_cast(CE->getOperand(0))) if (GV->isConstant() && !GV->isExternal()) if (Constant *V = - GetGEPGlobalInitializer(GV->getInitializer(), CE)) { + ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE)) { markConstant(IV, &I, V); return; } From lattner at cs.uiuc.edu Mon Sep 26 00:34:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 00:34:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200509260534.AAA08658@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.48 -> 1.49 --- Log message: Replace TraverseGEPInitializer with ConstantFoldLoadThroughGEPConstantExpr --- Diffs of the changes: (+5 -17) GlobalOpt.cpp | 22 +++++----------------- 1 files changed, 5 insertions(+), 17 deletions(-) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.48 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.49 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.48 Mon Sep 26 00:16:34 2005 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 26 00:34:07 2005 @@ -297,21 +297,6 @@ return 0; } -static Constant *TraverseGEPInitializer(User *GEP, Constant *Init) { - if (Init == 0) return 0; - if (GEP->getNumOperands() == 1 || - !isa(GEP->getOperand(1)) || - !cast(GEP->getOperand(1))->isNullValue()) - return 0; - - for (unsigned i = 2, e = GEP->getNumOperands(); i != e; ++i) { - ConstantInt *Idx = dyn_cast(GEP->getOperand(i)); - if (!Idx) return 0; - Init = getAggregateConstantElement(Init, Idx); - if (Init == 0) return 0; - } - return Init; -} /// CleanupConstantGlobalUsers - We just marked GV constant. Loop over all /// users of the global, cleaning up the obvious ones. This is largely just a @@ -335,7 +320,7 @@ Changed = true; } else if (ConstantExpr *CE = dyn_cast(U)) { if (CE->getOpcode() == Instruction::GetElementPtr) { - Constant *SubInit = TraverseGEPInitializer(CE, Init); + Constant *SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE); Changed |= CleanupConstantGlobalUsers(CE, SubInit); } else if (CE->getOpcode() == Instruction::Cast && isa(CE->getType())) { @@ -348,7 +333,10 @@ Changed = true; } } else if (GetElementPtrInst *GEP = dyn_cast(U)) { - Constant *SubInit = TraverseGEPInitializer(GEP, Init); + Constant *SubInit = 0; + ConstantExpr *CE = dyn_cast(ConstantFoldInstruction(GEP)); + if (CE && CE->getOpcode() == Instruction::GetElementPtr) + SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE); Changed |= CleanupConstantGlobalUsers(GEP, SubInit); if (GEP->use_empty()) { From lattner at cs.uiuc.edu Mon Sep 26 01:52:01 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 01:52:01 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll Message-ID: <200509260652.BAA08964@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/GlobalOpt: ctor-list-opt.ll updated: 1.4 -> 1.5 --- Log message: add another case, this one that uses getelementptr instructions --- Diffs of the changes: (+13 -1) ctor-list-opt.ll | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletion(-) Index: llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll diff -u llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.4 llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.5 --- llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.4 Mon Sep 26 00:14:48 2005 +++ llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll Mon Sep 26 01:51:50 2005 @@ -1,12 +1,13 @@ ; RUN: llvm-as < %s | opt -globalopt -disable-output && ; RUN: llvm-as < %s | opt -globalopt | llvm-dis | not grep CTOR -%llvm.global_ctors = appending global [6 x { int, void ()* }] [ +%llvm.global_ctors = appending global [7 x { int, void ()* }] [ { int, void ()* } { int 65535, void ()* %CTOR1 }, { int, void ()* } { int 65535, void ()* %CTOR1 }, { int, void ()* } { int 65535, void ()* %CTOR2 }, { int, void ()* } { int 65535, void ()* %CTOR3 }, { int, void ()* } { int 65535, void ()* %CTOR4 }, + { int, void ()* } { int 65535, void ()* %CTOR5 }, { int, void ()* } { int 2147483647, void ()* null } ] @@ -14,6 +15,8 @@ %G2 = global int 0 %G3 = global int -123 +%X = global {int, [2 x int]} { int 0, [2 x int] [ int 17, int 21] } + %CTORGV = internal global bool false ;; Should become constant after eval implementation @@ -48,6 +51,15 @@ ret void } +internal void %CTOR5() { + %X.2p = getelementptr {int,[2 x int]}* %X, int 0, uint 1, int 0 + %X.2 = load int* %X.2p + %X.1p = getelementptr {int,[2 x int]}* %X, int 0, uint 0 + store int %X.2, int* %X.1p + store int 42, int* %X.2p + ret void +} + bool %accessor() { %V = load bool* %CTORGV ;; constant true ret bool %V From lattner at cs.uiuc.edu Mon Sep 26 01:52:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 01:52:55 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200509260652.BAA08997@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.49 -> 1.50 --- Log message: Implement loads/stores through GEP's of globals. This implements ctor-list-opt.ll:CTOR5. --- Diffs of the changes: (+98 -6) GlobalOpt.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 98 insertions(+), 6 deletions(-) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.49 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.50 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.49 Mon Sep 26 00:34:07 2005 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 26 01:52:44 2005 @@ -334,7 +334,8 @@ } } else if (GetElementPtrInst *GEP = dyn_cast(U)) { Constant *SubInit = 0; - ConstantExpr *CE = dyn_cast(ConstantFoldInstruction(GEP)); + ConstantExpr *CE = + dyn_cast_or_null(ConstantFoldInstruction(GEP)); if (CE && CE->getOpcode() == Instruction::GetElementPtr) SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE); Changed |= CleanupConstantGlobalUsers(GEP, SubInit); @@ -1240,15 +1241,97 @@ static bool isSimpleEnoughPointerToCommit(Constant *C) { if (GlobalVariable *GV = dyn_cast(C)) return !GV->isExternal(); // reject external globals. + if (ConstantExpr *CE = dyn_cast(C)) + // Handle a constantexpr gep. + if (CE->getOpcode() == Instruction::GetElementPtr && + isa(CE->getOperand(0))) { + GlobalVariable *GV = cast(CE->getOperand(0)); + return GV->hasInitializer() && + ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE); + } return false; } +/// EvaluateStoreInto - Evaluate a piece of a constantexpr store into a global +/// initializer. This returns 'Init' modified to reflect 'Val' stored into it. +/// At this point, the GEP operands of Addr [0, OpNo) have been stepped into. +static Constant *EvaluateStoreInto(Constant *Init, Constant *Val, + ConstantExpr *Addr, unsigned OpNo) { + // Base case of the recursion. + if (OpNo == Addr->getNumOperands()) { + assert(Val->getType() == Init->getType() && "Type mismatch!"); + return Val; + } + + if (const StructType *STy = dyn_cast(Init->getType())) { + std::vector Elts; + + // Break up the constant into its elements. + if (ConstantStruct *CS = dyn_cast(Init)) { + for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) + Elts.push_back(CS->getOperand(i)); + } else if (isa(Init)) { + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) + Elts.push_back(Constant::getNullValue(STy->getElementType(i))); + } else if (isa(Init)) { + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) + Elts.push_back(UndefValue::get(STy->getElementType(i))); + } else { + assert(0 && "This code is out of sync with " + " ConstantFoldLoadThroughGEPConstantExpr"); + } + + // Replace the element that we are supposed to. + ConstantUInt *CU = cast(Addr->getOperand(OpNo)); + assert(CU->getValue() < STy->getNumElements() && + "Struct index out of range!"); + unsigned Idx = (unsigned)CU->getValue(); + Elts[Idx] = EvaluateStoreInto(Elts[Idx], Val, Addr, OpNo+1); + + // Return the modified struct. + return ConstantStruct::get(Elts); + } else { + ConstantInt *CI = cast(Addr->getOperand(OpNo)); + const ArrayType *ATy = cast(Init->getType()); + + // Break up the array into elements. + std::vector Elts; + if (ConstantArray *CA = dyn_cast(Init)) { + for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) + Elts.push_back(CA->getOperand(i)); + } else if (isa(Init)) { + Constant *Elt = Constant::getNullValue(ATy->getElementType()); + Elts.assign(ATy->getNumElements(), Elt); + } else if (isa(Init)) { + Constant *Elt = UndefValue::get(ATy->getElementType()); + Elts.assign(ATy->getNumElements(), Elt); + } else { + assert(0 && "This code is out of sync with " + " ConstantFoldLoadThroughGEPConstantExpr"); + } + + assert((uint64_t)CI->getRawValue() < ATy->getNumElements()); + Elts[(uint64_t)CI->getRawValue()] = + EvaluateStoreInto(Elts[(uint64_t)CI->getRawValue()], Val, Addr, OpNo+1); + return ConstantArray::get(ATy, Elts); + } +} + /// CommitValueTo - We have decided that Addr (which satisfies the predicate /// isSimpleEnoughPointerToCommit) should get Val as its value. Make it happen. static void CommitValueTo(Constant *Val, Constant *Addr) { - GlobalVariable *GV = cast(Addr); - assert(GV->hasInitializer()); - GV->setInitializer(Val); + if (GlobalVariable *GV = dyn_cast(Addr)) { + assert(GV->hasInitializer()); + GV->setInitializer(Val); + return; + } + + ConstantExpr *CE = cast(Addr); + GlobalVariable *GV = cast(CE->getOperand(0)); + + Constant *Init = GV->getInitializer(); + Init = EvaluateStoreInto(Init, Val, CE, 2); + GV->setInitializer(Init); } /// ComputeLoadResult - Return the value that would be computed by a load from @@ -1266,9 +1349,18 @@ if (GV->hasInitializer()) return GV->getInitializer(); return 0; - } else { - return 0; // don't know how to evaluate. } + + // Handle a constantexpr getelementptr. + if (ConstantExpr *CE = dyn_cast(P)) + if (CE->getOpcode() == Instruction::GetElementPtr && + isa(CE->getOperand(0))) { + GlobalVariable *GV = cast(CE->getOperand(0)); + if (GV->hasInitializer()) + return ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE); + } + + return 0; // don't know how to evaluate. } /// EvaluateStaticConstructor - Evaluate static constructors in the function, if From lattner at cs.uiuc.edu Mon Sep 26 02:34:47 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 02:34:47 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200509260734.CAA09271@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.50 -> 1.51 --- Log message: Add a debug printout, fix a crash on kc++ --- Diffs of the changes: (+6 -1) GlobalOpt.cpp | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.50 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.51 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.50 Mon Sep 26 01:52:44 2005 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 26 02:34:35 2005 @@ -320,7 +320,9 @@ Changed = true; } else if (ConstantExpr *CE = dyn_cast(U)) { if (CE->getOpcode() == Instruction::GetElementPtr) { - Constant *SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE); + Constant *SubInit = 0; + if (Init) + SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE); Changed |= CleanupConstantGlobalUsers(CE, SubInit); } else if (CE->getOpcode() == Instruction::Cast && isa(CE->getType())) { @@ -1481,6 +1483,9 @@ for (std::map::iterator I = MutatedMemory.begin(), E = MutatedMemory.end(); I != E; ++I) CommitValueTo(I->second, I->first); + + DEBUG(std::cerr << "FULLY EVALUATED GLOBAL CTOR FUNCTION '" << + F->getName() << "'\n"); return true; } From lattner at cs.uiuc.edu Mon Sep 26 12:06:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 12:06:44 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll Message-ID: <200509261706.MAA10927@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/GlobalOpt: ctor-list-opt.ll updated: 1.5 -> 1.6 --- Log message: Testcase that uses an alloca --- Diffs of the changes: (+14 -1) ctor-list-opt.ll | 15 ++++++++++++++- 1 files changed, 14 insertions(+), 1 deletion(-) Index: llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll diff -u llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.5 llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.6 --- llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.5 Mon Sep 26 01:51:50 2005 +++ llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll Mon Sep 26 12:06:32 2005 @@ -1,13 +1,14 @@ ; RUN: llvm-as < %s | opt -globalopt -disable-output && ; RUN: llvm-as < %s | opt -globalopt | llvm-dis | not grep CTOR -%llvm.global_ctors = appending global [7 x { int, void ()* }] [ +%llvm.global_ctors = appending global [8 x { int, void ()* }] [ { int, void ()* } { int 65535, void ()* %CTOR1 }, { int, void ()* } { int 65535, void ()* %CTOR1 }, { int, void ()* } { int 65535, void ()* %CTOR2 }, { int, void ()* } { int 65535, void ()* %CTOR3 }, { int, void ()* } { int 65535, void ()* %CTOR4 }, { int, void ()* } { int 65535, void ()* %CTOR5 }, + { int, void ()* } { int 65535, void ()* %CTOR6 }, { int, void ()* } { int 2147483647, void ()* null } ] @@ -17,6 +18,8 @@ %X = global {int, [2 x int]} { int 0, [2 x int] [ int 17, int 21] } +%Y = global int -1 + %CTORGV = internal global bool false ;; Should become constant after eval implementation @@ -60,6 +63,16 @@ ret void } +internal void %CTOR6() { + %A = alloca int + %y = load int* %Y + store int %y, int* %A + %Av = load int* %A + %Av1 = add int %Av, 1 + store int %Av1, int* %Y + ret void +} + bool %accessor() { %V = load bool* %CTORGV ;; constant true ret bool %V From lattner at cs.uiuc.edu Mon Sep 26 12:07:20 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 12:07:20 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200509261707.MAA10982@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.51 -> 1.52 --- Log message: Add support for alloca, implementing ctor-list-opt.ll:CTOR6 --- Diffs of the changes: (+48 -17) GlobalOpt.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 48 insertions(+), 17 deletions(-) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.51 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.52 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.51 Mon Sep 26 02:34:35 2005 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 26 12:07:09 2005 @@ -1380,21 +1380,28 @@ /// we can only evaluate any one basic block at most once. This set keeps /// track of what we have executed so we can detect recursive cases etc. std::set ExecutedBlocks; + + /// AllocaTmps - To 'execute' an alloca, we create a temporary global variable + /// to represent its body. This allows us to delete the temporary globals + /// when we are done. + std::vector AllocaTmps; // CurInst - The current instruction we're evaluating. BasicBlock::iterator CurInst = F->begin()->begin(); ExecutedBlocks.insert(F->begin()); + bool EvaluationSuccessful = false; + // This is the main evaluation loop. while (1) { Constant *InstResult = 0; if (StoreInst *SI = dyn_cast(CurInst)) { - if (SI->isVolatile()) return false; // no volatile accesses. + if (SI->isVolatile()) break; // no volatile accesses. Constant *Ptr = getVal(Values, SI->getOperand(1)); if (!isSimpleEnoughPointerToCommit(Ptr)) // If this is too complex for us to commit, reject it. - return false; + break; Constant *Val = getVal(Values, SI->getOperand(0)); MutatedMemory[Ptr] = Val; } else if (BinaryOperator *BO = dyn_cast(CurInst)) { @@ -1419,10 +1426,18 @@ GEPOps.push_back(getVal(Values, GEP->getOperand(i))); InstResult = ConstantExpr::getGetElementPtr(P, GEPOps); } else if (LoadInst *LI = dyn_cast(CurInst)) { - if (LI->isVolatile()) return false; // no volatile accesses. + if (LI->isVolatile()) break; // no volatile accesses. InstResult = ComputeLoadResult(getVal(Values, LI->getOperand(0)), MutatedMemory); - if (InstResult == 0) return false; // Could not evaluate load. + if (InstResult == 0) break; // Could not evaluate load. + } else if (AllocaInst *AI = dyn_cast(CurInst)) { + if (AI->isArrayAllocation()) break; // Cannot handle array allocs. + const Type *Ty = AI->getType()->getElementType(); + AllocaTmps.push_back(new GlobalVariable(Ty, false, + GlobalValue::InternalLinkage, + UndefValue::get(Ty), + AI->getName())); + InstResult = AllocaTmps.back(); } else if (TerminatorInst *TI = dyn_cast(CurInst)) { BasicBlock *NewBB = 0; if (BranchInst *BI = dyn_cast(CurInst)) { @@ -1431,27 +1446,28 @@ } else { ConstantBool *Cond = dyn_cast(getVal(Values, BI->getCondition())); - if (!Cond) return false; // Cannot determine. + if (!Cond) break; // Cannot determine. NewBB = BI->getSuccessor(!Cond->getValue()); } } else if (SwitchInst *SI = dyn_cast(CurInst)) { ConstantInt *Val = dyn_cast(getVal(Values, SI->getCondition())); - if (!Val) return false; // Cannot determine. + if (!Val) break; // Cannot determine. NewBB = SI->getSuccessor(SI->findCaseValue(Val)); } else if (ReturnInst *RI = dyn_cast(CurInst)) { assert(RI->getNumOperands() == 0); + EvaluationSuccessful = true; break; // We succeeded at evaluating this ctor! } else { // unwind, unreachable. - return false; // Cannot handle this terminator. + break; // Cannot handle this terminator. } // Okay, we succeeded in evaluating this control flow. See if we have // executed the new block before. If so, we have a looping or recursive // function, which we cannot evaluate in reasonable time. if (!ExecutedBlocks.insert(NewBB).second) - return false; // Recursed! + break; // Recursed/looped! // Okay, we have never been in this block before. Check to see if there // are any PHI nodes. If so, evaluate them with information about where @@ -1468,7 +1484,7 @@ // TODO: use ConstantFoldCall for function calls. // Did not know how to evaluate this! - return false; + break; } if (!CurInst->use_empty()) @@ -1477,16 +1493,31 @@ // Advance program counter. ++CurInst; } + + if (EvaluationSuccessful) { + // We succeeded at evaluation: commit the result. + DEBUG(std::cerr << "FULLY EVALUATED GLOBAL CTOR FUNCTION '" << + F->getName() << "'\n"); + for (std::map::iterator I = MutatedMemory.begin(), + E = MutatedMemory.end(); I != E; ++I) + CommitValueTo(I->second, I->first); + } - // If we get here, we know that we succeeded at evaluation: commit the result. - // - for (std::map::iterator I = MutatedMemory.begin(), - E = MutatedMemory.end(); I != E; ++I) - CommitValueTo(I->second, I->first); + // At this point, we are done interpreting. If we created any 'alloca' + // temporaries, release them now. + while (!AllocaTmps.empty()) { + GlobalVariable *Tmp = AllocaTmps.back(); + AllocaTmps.pop_back(); + + // If there are still users of the alloca, the program is doing something + // silly, e.g. storing the address of the alloca somewhere and using it + // later. Since this is undefined, we'll just make it be null. + if (!Tmp->use_empty()) + Tmp->replaceAllUsesWith(Constant::getNullValue(Tmp->getType())); + delete Tmp; + } - DEBUG(std::cerr << "FULLY EVALUATED GLOBAL CTOR FUNCTION '" << - F->getName() << "'\n"); - return true; + return EvaluationSuccessful; } From lattner at cs.uiuc.edu Mon Sep 26 15:38:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 15:38:32 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200509262038.PAA12794@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.52 -> 1.53 --- Log message: Remove some dead code. ctor evaluation subsumes empty ctor elim --- Diffs of the changes: (+0 -12) GlobalOpt.cpp | 12 ------------ 1 files changed, 12 deletions(-) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.52 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.53 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.52 Mon Sep 26 12:07:09 2005 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 26 15:38:20 2005 @@ -45,7 +45,6 @@ "Number of global vars shrunk to booleans"); Statistic<> NumFastCallFns("globalopt", "Number of functions converted to fastcc"); - Statistic<> NumEmptyCtor ("globalopt", "Number of empty ctors removed"); Statistic<> NumCtorsEvaluated("globalopt","Number of static ctors evaluated"); struct GlobalOpt : public ModulePass { @@ -926,7 +925,6 @@ Module::global_iterator &GVI) { std::set PHIUsers; GlobalStatus GS; - PHIUsers.clear(); GV->removeDeadConstantUsers(); if (GV->use_empty()) { @@ -1552,16 +1550,6 @@ ++NumCtorsEvaluated; continue; } - - // If the function is empty, just remove it from the ctor list. - if (isa(F->begin()->getTerminator()) && - &F->begin()->front() == F->begin()->getTerminator()) { - Ctors.erase(Ctors.begin()+i); - MadeChange = true; - --i; - ++NumEmptyCtor; - continue; - } } if (!MadeChange) return false; From lattner at cs.uiuc.edu Mon Sep 26 16:53:37 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 16:53:37 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200509262153.QAA13211@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.41 -> 1.42 --- Log message: implement a fixme: only select values once, even if used multiple times. --- Diffs of the changes: (+8 -5) DAGISelEmitter.cpp | 13 ++++++++----- 1 files changed, 8 insertions(+), 5 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.41 llvm/utils/TableGen/DAGISelEmitter.cpp:1.42 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.41 Sun Sep 25 14:04:43 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Mon Sep 26 16:53:26 2005 @@ -1074,23 +1074,26 @@ << ".Val)) goto P" << PatternNo << "Fail;\n"; } - +/// CodeGenPatternResult - Emit the action for a pattern. Now that it has +/// matched, we actually have to build a DAG! unsigned DAGISelEmitter:: CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, std::map &VariableMap, - std::ostream &OS){ + std::ostream &OS) { // This is something selected from the pattern we matched. if (!N->getName().empty()) { - const std::string &Val = VariableMap[N->getName()]; + std::string &Val = VariableMap[N->getName()]; assert(!Val.empty() && "Variable referenced but not defined and not caught earlier!"); if (Val[0] == 'T' && Val[1] == 'm' && Val[2] == 'p') { // Already selected this operand, just return the tmpval. - // FIXME: DO THIS. + return atoi(Val.c_str()+3); } else { unsigned ResNo = Ctr++; OS << " SDOperand Tmp" << ResNo << " = Select(" << Val << ");\n"; - // FIXME: Add Tmp to VariableMap. + // Add Tmp to VariableMap, so that we don't multiply select this + // value if used multiple times by this pattern result. + Val = "Tmp"+utostr(ResNo); return ResNo; } } From jlaskey at apple.com Mon Sep 26 16:57:15 2005 From: jlaskey at apple.com (Jim Laskey) Date: Mon, 26 Sep 2005 16:57:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200509262157.QAA13240@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.22 -> 1.23 --- Log message: Addition of a simple two pass scheduler. This version is currently hacked up for testing and will require target machine info to do a proper scheduling. The simple scheduler can be turned on using -sched=simple (defaults to -sched=none) --- Diffs of the changes: (+773 -82) ScheduleDAG.cpp | 855 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 773 insertions(+), 82 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.22 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.23 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.22 Fri Sep 2 02:09:28 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Mon Sep 26 16:57:04 2005 @@ -7,8 +7,9 @@ // //===----------------------------------------------------------------------===// // -// This implements a simple code linearizer for DAGs. This is not a very good -// way to emit code, but gets working code quickly. +// This implements a simple two pass scheduler. The first pass attempts to push +// backward any lengthy instructions and critical paths. The second pass packs +// instructions into semi-optimal time slots. // //===----------------------------------------------------------------------===// @@ -22,8 +23,29 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include using namespace llvm; +namespace { + // Style of scheduling to use. + enum ScheduleChoices { + noScheduling, + simpleScheduling, + }; +} // namespace + +cl::opt ScheduleStyle("sched", + cl::desc("Choose scheduling style"), + cl::init(noScheduling), + cl::values( + clEnumValN(noScheduling, "none", + "Trivial emission with no analysis"), + clEnumValN(simpleScheduling, "simple", + "Minimize critical path and maximize processor utilization"), + clEnumValEnd)); + + #ifndef NDEBUG static cl::opt ViewDAGs("view-sched-dags", cl::Hidden, @@ -33,76 +55,681 @@ #endif namespace { - class SimpleSched { - SelectionDAG &DAG; - MachineBasicBlock *BB; - const TargetMachine &TM; - const TargetInstrInfo &TII; - const MRegisterInfo &MRI; - SSARegMap *RegMap; - MachineConstantPool *ConstPool; - - std::map EmittedOps; - public: - SimpleSched(SelectionDAG &D, MachineBasicBlock *bb) - : DAG(D), BB(bb), TM(D.getTarget()), TII(*TM.getInstrInfo()), - MRI(*TM.getRegisterInfo()), RegMap(BB->getParent()->getSSARegMap()), - ConstPool(BB->getParent()->getConstantPool()) { - assert(&TII && "Target doesn't provide instr info?"); - assert(&MRI && "Target doesn't provide register info?"); - } - - MachineBasicBlock *Run() { - Emit(DAG.getRoot()); - return BB; +//===----------------------------------------------------------------------===// +/// +/// BitsIterator - Provides iteration through individual bits in a bit vector. +/// +template +class BitsIterator { +private: + T Bits; // Bits left to iterate through + +public: + /// Ctor. + BitsIterator(T Initial) : Bits(Initial) {} + + /// Next - Returns the next bit set or zero if exhausted. + inline T Next() { + // Get the rightmost bit set + T Result = Bits & -Bits; + // Remove from rest + Bits &= ~Result; + // Return single bit or zero + return Result; + } +}; + +//===----------------------------------------------------------------------===// + + +//===----------------------------------------------------------------------===// +/// +/// ResourceTally - Manages the use of resources over time intervals. Each +/// item (slot) in the tally vector represents the resources used at a given +/// moment. A bit set to 1 indicates that a resource is in use, otherwise +/// available. An assumption is made that the tally is large enough to schedule +/// all current instructions (asserts otherwise.) +/// +template +class ResourceTally { +private: + std::vector Tally; // Resources used per slot + typedef typename std::vector::iterator Iter; + // Tally iterator + + /// AllInUse - Test to see if all of the resources in the slot are busy (set.) + inline bool AllInUse(Iter Cursor, unsigned ResourceSet) { + return (*Cursor & ResourceSet) == ResourceSet; + } + + /// Skip - Skip over slots that use all of the specified resource (all are + /// set.) + Iter Skip(Iter Cursor, unsigned ResourceSet) { + assert(ResourceSet && "At least one resource bit needs to bet set"); + + // Continue to the end + while (true) { + // Break out if one of the resource bits is not set + if (!AllInUse(Cursor, ResourceSet)) return Cursor; + // Try next slot + Cursor++; + assert(Cursor < Tally.end() && "Tally is not large enough for schedule"); } + } + + /// FindSlots - Starting from Begin, locate N consecutive slots where at least + /// one of the resource bits is available. Returns the address of first slot. + Iter FindSlots(Iter Begin, unsigned N, unsigned ResourceSet, + unsigned &Resource) { + // Track position + Iter Cursor = Begin; - private: - unsigned Emit(SDOperand Op); + // Try all possible slots forward + while (true) { + // Skip full slots + Cursor = Skip(Cursor, ResourceSet); + // Determine end of interval + Iter End = Cursor + N; + assert(End <= Tally.end() && "Tally is not large enough for schedule"); + + // Iterate thru each resource + BitsIterator Resources(ResourceSet & ~*Cursor); + while (unsigned Res = Resources.Next()) { + // Check if resource is available for next N slots + // Break out if resource is busy + Iter Interval = Cursor; + for (; Interval < End && !(*Interval & Res); Interval++) {} + + // If available for interval, return where and which resource + if (Interval == End) { + Resource = Res; + return Cursor; + } + // Otherwise, check if worth checking other resources + if (AllInUse(Interval, ResourceSet)) { + // Start looking beyond interval + Cursor = Interval; + break; + } + } + Cursor++; + } + } + + /// Reserve - Mark busy (set) the specified N slots. + void Reserve(Iter Begin, unsigned N, unsigned Resource) { + // Determine end of interval + Iter End = Begin + N; + assert(End <= Tally.end() && "Tally is not large enough for schedule"); + + // Set resource bit in each slot + for (; Begin < End; Begin++) + *Begin |= Resource; + } + +public: + /// Initialize - Resize and zero the tally to the specified number of time + /// slots. + inline void Initialize(unsigned N) { + Tally.assign(N, 0); // Initialize tally to all zeros. + } + + // FindAndReserve - Locate and mark busy (set) N bits started at slot I, using + // ResourceSet for choices. + unsigned FindAndReserve(unsigned I, unsigned N, unsigned ResourceSet) { + // Which resource used + unsigned Resource; + // Find slots for instruction. + Iter Where = FindSlots(Tally.begin() + I, N, ResourceSet, Resource); + // Reserve the slots + Reserve(Where, N, Resource); + // Return time slot (index) + return Where - Tally.begin(); + } + +}; +//===----------------------------------------------------------------------===// + + +//===----------------------------------------------------------------------===// +// This struct tracks information used to schedule the a node. +struct ScheduleInfo { + SDOperand Op; // Operand information + unsigned Latency; // Cycles to complete instruction + unsigned ResourceSet; // Bit vector of usable resources + bool IsBoundary; // Do not shift passed this instruction. + unsigned Slot; // Operand's time slot + + // Ctor. + ScheduleInfo(SDOperand op) + : Op(op) + , Latency(0) + , ResourceSet(0) + , IsBoundary(false) + , Slot(0) + {} +}; +//===----------------------------------------------------------------------===// + + +//===----------------------------------------------------------------------===// +class SimpleSched { +private: + // TODO - get ResourceSet from TII + enum { + RSInteger = 0x3, // Two integer units + RSFloat = 0xC, // Two float units + RSLoadStore = 0x30, // Two load store units + RSOther = 0 // Processing unit independent }; + + MachineBasicBlock *BB; // Current basic block + SelectionDAG &DAG; // DAG of the current basic block + const TargetMachine &TM; // Target processor + const TargetInstrInfo &TII; // Target instruction information + const MRegisterInfo &MRI; // Target processor register information + SSARegMap *RegMap; // Virtual/real register map + MachineConstantPool *ConstPool; // Target constant pool + std::vector Operands; // All operands to be scheduled + std::vector Ordering; // Emit ordering of operands + std::map Visited; // Operands that have been visited + ResourceTally Tally; // Resource usage tally + unsigned NSlots; // Total latency + std::mapVRMap; // Operand to VR map + static const unsigned NotFound = ~0U; // Search marker + +public: + + // Ctor. + SimpleSched(SelectionDAG &D, MachineBasicBlock *bb) + : BB(bb), DAG(D), TM(D.getTarget()), TII(*TM.getInstrInfo()), + MRI(*TM.getRegisterInfo()), RegMap(BB->getParent()->getSSARegMap()), + ConstPool(BB->getParent()->getConstantPool()), + NSlots(0) { + assert(&TII && "Target doesn't provide instr info?"); + assert(&MRI && "Target doesn't provide register info?"); + } + + // Run - perform scheduling. + MachineBasicBlock *Run() { + Schedule(); + return BB; + } + +private: + static bool isFlagDefiner(SDOperand Op) { return isFlagDefiner(Op.Val); } + static bool isFlagUser(SDOperand Op) { return isFlagUser(Op.Val); } + static bool isFlagDefiner(SDNode *A); + static bool isFlagUser(SDNode *A); + static bool isDefiner(SDNode *A, SDNode *B); + static bool isPassiveOperand(SDOperand Op); + void IncludeOperand(SDOperand Op); + void VisitAll(); + void Schedule(); + void GatherOperandInfo(); + bool isStrongDependency(SDOperand A, SDOperand B) { + return isStrongDependency(A.Val, B.Val); + } + bool isWeakDependency(SDOperand A, SDOperand B) { + return isWeakDependency(A.Val, B.Val); + } + static bool isStrongDependency(SDNode *A, SDNode *B); + static bool isWeakDependency(SDNode *A, SDNode *B); + void ScheduleBackward(); + void ScheduleForward(); + void EmitAll(); + void EmitFlagUsers(SDOperand Op); + static unsigned CountResults(SDOperand Op); + static unsigned CountOperands(SDOperand Op); + unsigned CreateVirtualRegisters(SDOperand Op, MachineInstr *MI, + unsigned NumResults, + const TargetInstrDescriptor &II); + unsigned Emit(SDOperand A); + + void printSI(std::ostream &O, ScheduleInfo *SI) const ; + void print(std::ostream &O) const ; + inline void dump(const char *tag) const { std::cerr << tag; dump(); } + void dump() const; +}; +//===----------------------------------------------------------------------===// + + +//===----------------------------------------------------------------------===// +class FlagUserIterator { +private: + SDNode *Definer; // Node defining flag + SDNode::use_iterator UI; // User node iterator + SDNode::use_iterator E; // End of user nodes + unsigned MinRes; // Minimum flag result + +public: + // Ctor. + FlagUserIterator(SDNode *D) + : Definer(D) + , UI(D->use_begin()) + , E(D->use_end()) + , MinRes(D->getNumValues()) { + // Find minimum flag result. + while (MinRes && D->getValueType(MinRes - 1) == MVT::Flag) --MinRes; + } + + /// isFlagUser - Return true if node uses definer's flag. + bool isFlagUser(SDNode *U) { + // For each operand (in reverse to only look at flags) + for (unsigned N = U->getNumOperands(); 0 < N--;) { + // Get operand + SDOperand Op = U->getOperand(N); + // Not user if there are no flags + if (Op.getValueType() != MVT::Flag) return false; + // Return true if it is one of the flag results + if (Op.Val == Definer && Op.ResNo >= MinRes) return true; + } + // Not a flag user + return false; + } + + SDNode *next() { + // Continue to next user + while (UI != E) { + // Next user node + SDNode *User = *UI++; + // Return true if is a flag user + if (isFlagUser(User)) return User; + } + + // No more user nodes + return NULL; + } +}; + +} // namespace + + +//===----------------------------------------------------------------------===// +/// isFlagDefiner - Returns true if the operand defines a flag result. +bool SimpleSched::isFlagDefiner(SDNode *A) { + unsigned N = A->getNumValues(); + return N && A->getValueType(N - 1) == MVT::Flag; } -unsigned SimpleSched::Emit(SDOperand Op) { - // Check to see if we have already emitted this. If so, return the value - // already emitted. Note that if a node has a single use it cannot be - // revisited, so don't bother putting it in the map. - unsigned *OpSlot; - if (Op.Val->hasOneUse()) { - OpSlot = 0; // No reuse possible. - } else { - std::map::iterator OpI = EmittedOps.lower_bound(Op.Val); - if (OpI != EmittedOps.end() && OpI->first == Op.Val) - return OpI->second + Op.ResNo; - OpSlot = &EmittedOps.insert(OpI, std::make_pair(Op.Val, 0))->second; +/// isFlagUser - Returns true if the operand uses a flag result. +/// +bool SimpleSched::isFlagUser(SDNode *A) { + unsigned N = A->getNumOperands(); + return N && A->getOperand(N - 1).getValueType() == MVT::Flag; +} + +/// isDefiner - Return true if Node A is a definder for B. +/// +bool SimpleSched::isDefiner(SDNode *A, SDNode *B) { + for (unsigned i = 0, N = B->getNumOperands(); i < N; i++) { + if (B->getOperand(i).Val == A) return true; + } + return false; +} + +/// isPassiveOperand - Return true if the operand is a non-scheduled leaf +/// operand. +bool SimpleSched::isPassiveOperand(SDOperand Op) { + if (isa(Op)) return true; + if (isa(Op)) return true; + if (isa(Op)) return true; + if (isa(Op)) return true; + if (isa(Op)) return true; + if (isa(Op)) return true; + if (isa(Op)) return true; + return false; +} + +/// IncludeOperand - Add operand to ScheduleInfo vector. +/// +void SimpleSched::IncludeOperand(SDOperand Op) { + // Ignore entry node + if (Op.getOpcode() == ISD::EntryToken) return; + // Check current count for operand + int Count = Visited[Op.Val]; + // If the operand is already in list + if (Count < 0) return; + // If this the first time then get count + if (!Count) Count = Op.Val->use_size(); + // Decrement count to indicate a visit + Count--; + // If count has gone to zero then add operand to list + if (!Count) { + // Add operand + Operands.push_back(ScheduleInfo(Op)); + // indicate operand has been added + Count--; } + // Mark as visited with new count + Visited[Op.Val] = Count; +} + +/// VisitAll - Visit each operand breadth-wise to produce an initial ordering. +/// Note that the ordering in the Operands vector is reversed. +void SimpleSched::VisitAll() { + // Add first element to list + Operands.push_back(DAG.getRoot()); + for (unsigned i = 0; i < Operands.size(); i++) { // note: size() varies + // Get next operand. Need copy because Operands vector is growing and + // addresses can be ScheduleInfo changing. + SDOperand Op = Operands[i].Op; + // Get the number of real operands + unsigned NodeOperands = CountOperands(Op); + // Get the total number of operands + unsigned NumOperands = Op.getNumOperands(); + + // Visit all operands skipping the Other operand if present + for (unsigned i = NumOperands; 0 < i--;) { + SDOperand OpI = Op.getOperand(i); + // Ignore passive operands + if (isPassiveOperand(OpI)) continue; + // Check out operand + IncludeOperand(OpI); + } + } + + // Add entry node last (IncludeOperand filters entry nodes) + if (DAG.getEntryNode().Val != DAG.getRoot().Val) + Operands.push_back(DAG.getEntryNode()); +} + +/// GatherOperandInfo - Get latency and resource information about each operand. +/// +void SimpleSched::GatherOperandInfo() { + // Add addresses of operand info to ordering vector + // Get number of operands + unsigned N = Operands.size(); + // FIXME: This is an ugly (but temporary!) hack to test the scheduler before + // we have real target info. + + // For each operand being scheduled + for (unsigned i = 0; i < N; i++) { + ScheduleInfo* SI = &Operands[N - i - 1]; + SDOperand Op = SI->Op; + MVT::ValueType VT = Op.Val->getValueType(0); + if (Op.isTargetOpcode()) { + MachineOpCode TOpc = Op.getTargetOpcode(); + // FIXME SI->Latency = std::max(1, TII.maxLatency(TOpc)); + // FIXME SI->ResourceSet = TII.resources(TOpc); + // There is a cost for keeping values across a call. + SI->IsBoundary = TII.isCall(TOpc); + + if (TII.isLoad(TOpc)) { + SI->ResourceSet = RSLoadStore; + SI->Latency = 5; + } else if (TII.isStore(TOpc)) { + SI->ResourceSet = RSLoadStore; + SI->Latency = 2; + } else if (MVT::isInteger(VT)) { + SI->ResourceSet = RSInteger; + SI->Latency = 2; + } else if (MVT::isFloatingPoint(VT)) { + SI->ResourceSet = RSFloat; + SI->Latency = 3; + } else { + SI->ResourceSet = RSOther; + SI->Latency = 0; + } + } else { + if (MVT::isInteger(VT)) { + SI->ResourceSet = RSInteger; + SI->Latency = 2; + } else if (MVT::isFloatingPoint(VT)) { + SI->ResourceSet = RSFloat; + SI->Latency = 3; + } else { + SI->ResourceSet = RSOther; + SI->Latency = 0; + } + } + + // Add one slot for the instruction itself + SI->Latency++; + + // Sum up all the latencies for max tally size + NSlots += SI->Latency; + + // Place in initial sorted order + // FIXME - PUNT - ignore flag users + if (!isFlagUser(Op)) Ordering.push_back(SI); + } +} + +/// isStrongDependency - Return true if operand A has results used by operand B. +/// I.E., B must wait for latency of A. +bool SimpleSched::isStrongDependency(SDNode *A, SDNode *B) { + // If A defines for B then it's a strong dependency + if (isDefiner(A, B)) return true; + // If A defines a flag then it's users are part of the dependency + if (isFlagDefiner(A)) { + // Check each flag user + FlagUserIterator FI(A); + while (SDNode *User = FI.next()) { + // If flag user has strong dependency so does B + if (isStrongDependency(User, B)) return true; + } + } + // If B defines a flag then it's users are part of the dependency + if (isFlagDefiner(B)) { + // Check each flag user + FlagUserIterator FI(B); + while (SDNode *User = FI.next()) { + // If flag user has strong dependency so does B + if (isStrongDependency(A, User)) return true; + } + } + return false; +} + +/// isWeakDependency Return true if operand A produces a result that will +/// conflict with operands of B. +bool SimpleSched::isWeakDependency(SDNode *A, SDNode *B) { + // TODO check for conflicting real registers and aliases + return A->getOpcode() == ISD::EntryToken || isStrongDependency(B, A); +} + +/// ScheduleBackward - Schedule instructions so that any long latency +/// instructions and the critical path get pushed back in time. Time is run in +/// reverse to allow code reuse of the Tally and eliminate the overhead of +/// biasing every slot indices against NSlots. +void SimpleSched::ScheduleBackward() { + // Size and clear the resource tally + Tally.Initialize(NSlots); + // Get number of operands to schedule + unsigned N = Ordering.size(); + + // For each operand being scheduled + for (unsigned i = N; 0 < i--;) { + ScheduleInfo *SI = Ordering[i]; + // Track insertion + unsigned Slot = NotFound; + + // Compare against those previously scheduled operands + for (unsigned j = i + 1; j < N; j++) { + // Get following instruction + ScheduleInfo *Other = Ordering[j]; + + // Check dependency against previously inserted operands + if (isStrongDependency(SI->Op, Other->Op)) { + Slot = Other->Slot + Other->Latency; + break; + } else if (SI->IsBoundary || Other->IsBoundary || + isWeakDependency(SI->Op, Other->Op)) { + Slot = Other->Slot; + break; + } + } + + // If independent of others (or first entry) + if (Slot == NotFound) Slot = 0; + + // Find a slot where the needed resources are available + if (SI->ResourceSet) + Slot = Tally.FindAndReserve(Slot, SI->Latency, SI->ResourceSet); + + // Set operand slot + SI->Slot = Slot; + + // Insert sort based on slot + unsigned j = i + 1; + for (; j < N; j++) { + // Get following instruction + ScheduleInfo *Other = Ordering[j]; + // Should we look further + if (Slot >= Other->Slot) break; + // Shuffle other into ordering + Ordering[j - 1] = Other; + } + // Insert operand in proper slot + if (j != i + 1) Ordering[j - 1] = SI; + } +} + +/// ScheduleForward - Schedule instructions to maximize packing. +/// +void SimpleSched::ScheduleForward() { + // Size and clear the resource tally + Tally.Initialize(NSlots); + // Get number of operands to schedule + unsigned N = Ordering.size(); + + // For each operand being scheduled + for (unsigned i = 0; i < N; i++) { + ScheduleInfo *SI = Ordering[i]; + // Track insertion + unsigned Slot = NotFound; + + // Compare against those previously scheduled operands + for (unsigned j = i; 0 < j--;) { + // Get following instruction + ScheduleInfo *Other = Ordering[j]; + + // Check dependency against previously inserted operands + if (isStrongDependency(Other->Op, SI->Op)) { + Slot = Other->Slot + Other->Latency; + break; + } else if (SI->IsBoundary || Other->IsBoundary || + isWeakDependency(Other->Op, SI->Op)) { + Slot = Other->Slot; + break; + } + } + + // If independent of others (or first entry) + if (Slot == NotFound) Slot = 0; + + // Find a slot where the needed resources are available + if (SI->ResourceSet) + Slot = Tally.FindAndReserve(Slot, SI->Latency, SI->ResourceSet); + + // Set operand slot + SI->Slot = Slot; + + // Insert sort based on slot + unsigned j = i; + for (; 0 < j--;) { + // Get following instruction + ScheduleInfo *Other = Ordering[j]; + // Should we look further + if (Slot >= Other->Slot) break; + // Shuffle other into ordering + Ordering[j + 1] = Other; + } + // Insert operand in proper slot + if (j != i) Ordering[j + 1] = SI; + } +} + +/// EmitAll - Emit all operands in schedule sorted order. +/// +void SimpleSched::EmitAll() { + // For each operand in the ordering + for (unsigned i = 0, N = Ordering.size(); i < N; i++) { + // Get the scheduling info + ScheduleInfo *SI = Ordering[i]; + // Get the operand + SDOperand Op = SI->Op; + // Emit the operand + Emit(Op); + // FIXME - PUNT - If Op defines a flag then it's users need to be emitted now + if (isFlagDefiner(Op)) EmitFlagUsers(Op); + } +} + +/// EmitFlagUsers - Emit users of operands flag. +/// +void SimpleSched::EmitFlagUsers(SDOperand Op) { + // Check each flag user + FlagUserIterator FI(Op.Val); + while (SDNode *User = FI.next()) { + // Construct user node as operand + SDOperand OpU(User, 0); + // Emit user node + Emit(OpU); + // If user defines a flag then it's users need to be emitted now + if (isFlagDefiner(User)) EmitFlagUsers(OpU); + } +} + +/// CountResults - The results of target nodes have register or immediate +/// operands first, then an optional chain, and optional flag operands (which do +/// not go into the machine instrs.) +unsigned SimpleSched::CountResults(SDOperand Op) { + unsigned N = Op.Val->getNumValues(); + while (N && Op.Val->getValueType(N - 1) == MVT::Flag) + --N; + if (N && Op.Val->getValueType(N - 1) == MVT::Other) + --N; // Skip over chain result. + return N; +} + +/// CountOperands The inputs to target nodes have any actual inputs first, +/// followed by an optional chain operand, then flag operands. Compute the +/// number of actual operands that will go into the machine instr. +unsigned SimpleSched::CountOperands(SDOperand Op) { + unsigned N = Op.getNumOperands(); + while (N && Op.getOperand(N - 1).getValueType() == MVT::Flag) + --N; + if (N && Op.getOperand(N - 1).getValueType() == MVT::Other) + --N; // Ignore chain if it exists. + return N; +} + +/// CreateVirtualRegisters - Add result register values for things that are +/// defined by this instruction. +unsigned SimpleSched::CreateVirtualRegisters(SDOperand Op, MachineInstr *MI, + unsigned NumResults, + const TargetInstrDescriptor &II) { + // Create the result registers for this node and add the result regs to + // the machine instruction. + const TargetOperandInfo *OpInfo = II.OpInfo; + unsigned ResultReg = RegMap->createVirtualRegister(OpInfo[0].RegClass); + MI->addRegOperand(ResultReg, MachineOperand::Def); + for (unsigned i = 1; i != NumResults; ++i) { + assert(OpInfo[i].RegClass && "Isn't a register operand!"); + MI->addRegOperand(RegMap->createVirtualRegister(OpInfo[0].RegClass), + MachineOperand::Def); + } + return ResultReg; +} + +/// Emit - Generate machine code for an operand and needed dependencies. +/// +unsigned SimpleSched::Emit(SDOperand Op) { + std::map::iterator OpI = VRMap.lower_bound(Op.Val); + if (OpI != VRMap.end() && OpI->first == Op.Val) + return OpI->second + Op.ResNo; + unsigned &OpSlot = VRMap.insert(OpI, std::make_pair(Op.Val, 0))->second; unsigned ResultReg = 0; if (Op.isTargetOpcode()) { unsigned Opc = Op.getTargetOpcode(); const TargetInstrDescriptor &II = TII.get(Opc); - // The results of target nodes have register or immediate operands first, - // then an optional chain, and optional flag operands (which do not go into - // the machine instrs). - unsigned NumResults = Op.Val->getNumValues(); - while (NumResults && Op.Val->getValueType(NumResults-1) == MVT::Flag) - --NumResults; - if (NumResults && Op.Val->getValueType(NumResults-1) == MVT::Other) - --NumResults; // Skip over chain result. - - // The inputs to target nodes have any actual inputs first, followed by an - // optional chain operand, then flag operands. Compute the number of actual - // operands that will go into the machine instr. - unsigned NodeOperands = Op.getNumOperands(); - while (NodeOperands && - Op.getOperand(NodeOperands-1).getValueType() == MVT::Flag) - --NodeOperands; - - if (NodeOperands && // Ignore chain if it exists. - Op.getOperand(NodeOperands-1).getValueType() == MVT::Other) - --NodeOperands; - - unsigned NumMIOperands = NodeOperands+NumResults; + unsigned NumResults = CountResults(Op); + unsigned NodeOperands = CountOperands(Op); + unsigned NumMIOperands = NodeOperands + NumResults; #ifndef NDEBUG assert((unsigned(II.numOperands) == NumMIOperands || II.numOperands == -1)&& "#operands for dag node doesn't match .td file!"); @@ -113,24 +740,14 @@ // Add result register values for things that are defined by this // instruction. - if (NumResults) { - // Create the result registers for this node and add the result regs to - // the machine instruction. - const TargetOperandInfo *OpInfo = II.OpInfo; - ResultReg = RegMap->createVirtualRegister(OpInfo[0].RegClass); - MI->addRegOperand(ResultReg, MachineOperand::Def); - for (unsigned i = 1; i != NumResults; ++i) { - assert(OpInfo[i].RegClass && "Isn't a register operand!"); - MI->addRegOperand(RegMap->createVirtualRegister(OpInfo[0].RegClass), - MachineOperand::Def); - } - } + if (NumResults) ResultReg = CreateVirtualRegisters(Op, MI, NumResults, II); // If there is a token chain operand, emit it first, as a hack to get avoid // really bad cases. if (Op.getNumOperands() > NodeOperands && - Op.getOperand(NodeOperands).getValueType() == MVT::Other) + Op.getOperand(NodeOperands).getValueType() == MVT::Other) { Emit(Op.getOperand(NodeOperands)); + } // Emit all of the actual operands of this instruction, adding them to the // instruction as appropriate. @@ -179,7 +796,7 @@ unsigned i = NodeOperands; if (Op.getOperand(i).getValueType() == MVT::Other) ++i; // the chain is already selected. - for (; i != Op.getNumOperands(); ++i) { + for (unsigned N = Op.getNumOperands(); i < N; i++) { assert(Op.getOperand(i).getValueType() == MVT::Flag && "Must be flag operands!"); Emit(Op.getOperand(i)); @@ -201,17 +818,22 @@ assert(0 && "This target-independent node should have been selected!"); case ISD::EntryToken: break; case ISD::TokenFactor: - for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) + for (unsigned i = 0, N = Op.getNumOperands(); i < N; i++) { Emit(Op.getOperand(i)); + } break; case ISD::CopyToReg: { SDOperand FlagOp; - if (Op.getNumOperands() == 4) + if (Op.getNumOperands() == 4) { FlagOp = Op.getOperand(3); - if (Op.getOperand(0).Val != FlagOp.Val) + } + if (Op.getOperand(0).Val != FlagOp.Val) { Emit(Op.getOperand(0)); // Emit the chain. + } unsigned Val = Emit(Op.getOperand(2)); - if (FlagOp.Val) Emit(FlagOp); + if (FlagOp.Val) { + Emit(FlagOp); + } MRI.copyRegToReg(*BB, BB->end(), cast(Op.getOperand(1))->getReg(), Val, RegMap->getRegClass(Val)); @@ -244,14 +866,83 @@ } } } - - if (OpSlot) *OpSlot = ResultReg; + + OpSlot = ResultReg; return ResultReg+Op.ResNo; } +/// Schedule - Order operands according to selected style. +/// +void SimpleSched::Schedule() { + switch (ScheduleStyle) { + case simpleScheduling: + // Breadth first walk of DAG + VisitAll(); + // Get latency and resource requirements + GatherOperandInfo(); + // Don't waste time if is only entry and return + if (Operands.size() > 2) { + DEBUG(dump("Pre-")); + // Push back long instructions and critical path + ScheduleBackward(); + DEBUG(dump("Mid-")); + // Pack instructions to maximize resource utilization + ScheduleForward(); + DEBUG(dump("Post-")); + // Emit in scheduled order + EmitAll(); + break; + } // fall thru + case noScheduling: + // Emit instructions in using a DFS from the exit root + Emit(DAG.getRoot()); + break; + } +} + +/// printSI - Print schedule info. +/// +void SimpleSched::printSI(std::ostream &O, ScheduleInfo *SI) const { +#ifndef NDEBUG + using namespace std; + SDOperand Op = SI->Op; + O << " " + << hex << Op.Val + << ", RS=" << SI->ResourceSet + << ", Lat=" << SI->Latency + << ", Slot=" << SI->Slot + << ", ARITY=(" << Op.getNumOperands() << "," + << Op.Val->getNumValues() << ")" + << " " << Op.Val->getOperationName(&DAG); + if (isFlagDefiner(Op)) O << "<#"; + if (isFlagUser(Op)) O << ">#"; +#endif +} -/// Pick a safe ordering and emit instructions for each target node in the -/// graph. +/// print - Print ordering to specified output stream. +/// +void SimpleSched::print(std::ostream &O) const { +#ifndef NDEBUG + using namespace std; + O << "Ordering\n"; + for (unsigned i = 0, N = Ordering.size(); i < N; i++) { + printSI(O, Ordering[i]); + O << "\n"; + } +#endif +} + +/// dump - Print ordering to std::cerr. +/// +void SimpleSched::dump() const { + print(std::cerr); +} +//===----------------------------------------------------------------------===// + + +//===----------------------------------------------------------------------===// +/// ScheduleAndEmitDAG - Pick a safe ordering and emit instructions for each +/// target node in the graph. void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &SD) { if (ViewDAGs) SD.viewGraph(); BB = SimpleSched(SD, BB).Run(); From lattner at cs.uiuc.edu Mon Sep 26 16:59:46 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 16:59:46 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200509262159.QAA13303@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.42 -> 1.43 --- Log message: Emit the switch stmt cases in alphabetical order instead of pointer order, which is not stable. --- Diffs of the changes: (+19 -4) DAGISelEmitter.cpp | 23 +++++++++++++++++++---- 1 files changed, 19 insertions(+), 4 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.42 llvm/utils/TableGen/DAGISelEmitter.cpp:1.43 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.42 Mon Sep 26 16:53:26 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Mon Sep 26 16:59:35 2005 @@ -1200,6 +1200,20 @@ } }; + +namespace { + /// CompareByRecordName - An ordering predicate that implements less-than by + /// comparing the names records. + struct CompareByRecordName { + bool operator()(const Record *LHS, const Record *RHS) const { + // Sort by name first. + if (LHS->getName() < RHS->getName()) return true; + // If both names are equal, sort by pointer. + return LHS->getName() == RHS->getName() && LHS < RHS; + } + }; +} + void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { // Emit boilerplate. OS << "// The main instruction selector code.\n" @@ -1220,15 +1234,16 @@ << " return Select(N.getOperand(0));\n"; // Group the patterns by their top-level opcodes. - std::map > PatternsByOpcode; + std::map, + CompareByRecordName> PatternsByOpcode; for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) PatternsByOpcode[PatternsToMatch[i].first->getOperator()] .push_back(&PatternsToMatch[i]); // Loop over all of the case statements. - for (std::map >::iterator - PBOI = PatternsByOpcode.begin(), E = PatternsByOpcode.end(); PBOI != E; - ++PBOI) { + for (std::map, + CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(), + E = PatternsByOpcode.end(); PBOI != E; ++PBOI) { const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first); std::vector &Patterns = PBOI->second; From lattner at cs.uiuc.edu Mon Sep 26 17:10:35 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 17:10:35 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200509262210.RAA13416@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.43 -> 1.44 --- Log message: memoize the assert results --- Diffs of the changes: (+5 -2) DAGISelEmitter.cpp | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.43 llvm/utils/TableGen/DAGISelEmitter.cpp:1.44 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.43 Mon Sep 26 16:59:35 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Mon Sep 26 17:10:24 2005 @@ -1230,8 +1230,11 @@ << " case ISD::EntryToken: // These leaves remain the same.\n" << " return N;\n" << " case ISD::AssertSext:\n" - << " case ISD::AssertZext:\n" - << " return Select(N.getOperand(0));\n"; + << " case ISD::AssertZext: {\n" + << " SDOperand Tmp0 = Select(N.getOperand(0));\n" + << " if (!N.Val->hasOneUse()) CodeGenMap[N] = Tmp0;\n" + << " return Tmp0;\n" + << " }\n"; // Group the patterns by their top-level opcodes. std::map, From lattner at cs.uiuc.edu Mon Sep 26 17:20:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 17:20:28 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509262220.RAA13572@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.102 -> 1.103 --- Log message: minor pattern shuffling --- Diffs of the changes: (+3 -8) PowerPCInstrInfo.td | 11 +++-------- 1 files changed, 3 insertions(+), 8 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.102 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.103 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.102 Fri Sep 23 19:41:58 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Mon Sep 26 17:20:16 2005 @@ -182,7 +182,6 @@ // not needing a full list. class Pat : Pattern; - //===----------------------------------------------------------------------===// // PowerPC specific transformation functions and pattern fragments. // @@ -763,9 +762,9 @@ // PowerPC Instruction Patterns // -// REDUNDANT WITH INSTRUCTION DEFINITION, ONLY FOR TESTING. -def : Pat<(sext_inreg GPRC:$in, i8), - (EXTSB GPRC:$in)>; +// Arbitrary immediate support. Implement in terms of LIS/ORI. +def : Pat<(i32 imm:$imm), + (ORI (LIS (HI16 imm:$imm)), (LO16 imm:$imm))>; // or by an arbitrary immediate. def : Pat<(or GPRC:$in, imm:$imm), @@ -774,10 +773,6 @@ def : Pat<(xor GPRC:$in, imm:$imm), (XORIS (XORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>; -// Arbitrary immediate support. -def : Pat<(i32 imm:$imm), - (ORI (LIS (HI16 imm:$imm)), (LO16 imm:$imm))>; - // Same as above, but using a temporary. FIXME: implement temporaries :) /* From lattner at cs.uiuc.edu Mon Sep 26 19:14:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 19:14:53 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp Message-ID: <200509270014.TAA14166@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCTargetMachine.cpp updated: 1.67 -> 1.68 --- Log message: Move the post-lsr simplify cfg pass after lowereh, so it can clean up after eh lowering as well. --- Diffs of the changes: (+6 -2) PowerPCTargetMachine.cpp | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.67 llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.68 --- llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.67 Fri Sep 2 14:53:54 2005 +++ llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp Mon Sep 26 19:14:41 2005 @@ -71,13 +71,15 @@ // Run loop strength reduction before anything else. PM.add(createLoopStrengthReducePass()); - PM.add(createCFGSimplificationPass()); // FIXME: Implement efficient support for garbage collection intrinsics. PM.add(createLowerGCPass()); // FIXME: Implement the invoke/unwind instructions! PM.add(createLowerInvokePass()); + + // Clean up after other passes, e.g. merging critical edges. + PM.add(createCFGSimplificationPass()); // FIXME: Implement the switch instruction in the instruction selector! PM.add(createLowerSwitchPass()); @@ -126,7 +128,6 @@ // Run loop strength reduction before anything else. PM.add(createLoopStrengthReducePass()); - PM.add(createCFGSimplificationPass()); // FIXME: Implement efficient support for garbage collection intrinsics. PM.add(createLowerGCPass()); @@ -134,6 +135,9 @@ // FIXME: Implement the invoke/unwind instructions! PM.add(createLowerInvokePass()); + // Clean up after other passes, e.g. merging critical edges. + PM.add(createCFGSimplificationPass()); + // FIXME: Implement the switch instruction in the instruction selector! PM.add(createLowerSwitchPass()); From lattner at cs.uiuc.edu Mon Sep 26 23:27:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 23:27:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200509270427.XAA15113@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.53 -> 1.54 --- Log message: Refactor this code a bit, no functionality changes. --- Diffs of the changes: (+40 -22) GlobalOpt.cpp | 62 +++++++++++++++++++++++++++++++++++++--------------------- 1 files changed, 40 insertions(+), 22 deletions(-) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.53 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.54 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.53 Mon Sep 26 15:38:20 2005 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 26 23:27:01 2005 @@ -1363,33 +1363,26 @@ return 0; // don't know how to evaluate. } -/// EvaluateStaticConstructor - Evaluate static constructors in the function, if -/// we can. Return true if we can, false otherwise. -static bool EvaluateStaticConstructor(Function *F) { +/// EvaluateFunction - Evaluate a call to function F, returning true if +/// successful, false if we can't evaluate it. ActualArgs contains the formal +/// arguments for the function. +static bool EvaluateFunction(Function *F, + const std::vector &ActualArgs, + std::vector &CallStack, + std::map &MutatedMemory, + std::vector &AllocaTmps) { /// Values - As we compute SSA register values, we store their contents here. std::map Values; - - /// MutatedMemory - For each store we execute, we update this map. Loads - /// check this to get the most up-to-date value. If evaluation is successful, - /// this state is committed to the process. - std::map MutatedMemory; - + /// ExecutedBlocks - We only handle non-looping, non-recursive code. As such, /// we can only evaluate any one basic block at most once. This set keeps /// track of what we have executed so we can detect recursive cases etc. std::set ExecutedBlocks; - /// AllocaTmps - To 'execute' an alloca, we create a temporary global variable - /// to represent its body. This allows us to delete the temporary globals - /// when we are done. - std::vector AllocaTmps; - // CurInst - The current instruction we're evaluating. BasicBlock::iterator CurInst = F->begin()->begin(); ExecutedBlocks.insert(F->begin()); - bool EvaluationSuccessful = false; - // This is the main evaluation loop. while (1) { Constant *InstResult = 0; @@ -1454,8 +1447,7 @@ NewBB = SI->getSuccessor(SI->findCaseValue(Val)); } else if (ReturnInst *RI = dyn_cast(CurInst)) { assert(RI->getNumOperands() == 0); - EvaluationSuccessful = true; - break; // We succeeded at evaluating this ctor! + return true; // We succeeded at evaluating this ctor! } else { // unwind, unreachable. break; // Cannot handle this terminator. @@ -1492,10 +1484,34 @@ ++CurInst; } - if (EvaluationSuccessful) { + return false; +} + +/// EvaluateStaticConstructor - Evaluate static constructors in the function, if +/// we can. Return true if we can, false otherwise. +static bool EvaluateStaticConstructor(Function *F) { + /// MutatedMemory - For each store we execute, we update this map. Loads + /// check this to get the most up-to-date value. If evaluation is successful, + /// this state is committed to the process. + std::map MutatedMemory; + + /// AllocaTmps - To 'execute' an alloca, we create a temporary global variable + /// to represent its body. This vector is needed so we can delete the + /// temporary globals when we are done. + std::vector AllocaTmps; + + /// CallStack - This is used to detect recursion. In pathological situations + /// we could hit exponential behavior, but at least there is nothing + /// unbounded. + std::vector CallStack; + + // Call the function. + bool EvalSuccess = EvaluateFunction(F, std::vector(), CallStack, + MutatedMemory, AllocaTmps); + if (EvalSuccess) { // We succeeded at evaluation: commit the result. DEBUG(std::cerr << "FULLY EVALUATED GLOBAL CTOR FUNCTION '" << - F->getName() << "'\n"); + F->getName() << "' to " << MutatedMemory.size() << " stores.\n"); for (std::map::iterator I = MutatedMemory.begin(), E = MutatedMemory.end(); I != E; ++I) CommitValueTo(I->second, I->first); @@ -1506,7 +1522,7 @@ while (!AllocaTmps.empty()) { GlobalVariable *Tmp = AllocaTmps.back(); AllocaTmps.pop_back(); - + // If there are still users of the alloca, the program is doing something // silly, e.g. storing the address of the alloca somewhere and using it // later. Since this is undefined, we'll just make it be null. @@ -1515,10 +1531,12 @@ delete Tmp; } - return EvaluationSuccessful; + return EvalSuccess; } + + /// OptimizeGlobalCtorsList - Simplify and evaluation global ctors if possible. /// Return true if anything changed. bool GlobalOpt::OptimizeGlobalCtorsList(GlobalVariable *&GCL) { From lattner at cs.uiuc.edu Mon Sep 26 23:44:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 23:44:15 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll Message-ID: <200509270444.XAA15232@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/GlobalOpt: ctor-list-opt.ll updated: 1.6 -> 1.7 --- Log message: Add a more difficult testcase which uses a call to a helper function to do the initialization --- Diffs of the changes: (+14 -1) ctor-list-opt.ll | 15 ++++++++++++++- 1 files changed, 14 insertions(+), 1 deletion(-) Index: llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll diff -u llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.6 llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.7 --- llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.6 Mon Sep 26 12:06:32 2005 +++ llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll Mon Sep 26 23:44:04 2005 @@ -1,7 +1,7 @@ ; RUN: llvm-as < %s | opt -globalopt -disable-output && ; RUN: llvm-as < %s | opt -globalopt | llvm-dis | not grep CTOR -%llvm.global_ctors = appending global [8 x { int, void ()* }] [ +%llvm.global_ctors = appending global [9 x { int, void ()* }] [ { int, void ()* } { int 65535, void ()* %CTOR1 }, { int, void ()* } { int 65535, void ()* %CTOR1 }, { int, void ()* } { int 65535, void ()* %CTOR2 }, @@ -9,6 +9,7 @@ { int, void ()* } { int 65535, void ()* %CTOR4 }, { int, void ()* } { int 65535, void ()* %CTOR5 }, { int, void ()* } { int 65535, void ()* %CTOR6 }, + { int, void ()* } { int 65535, void ()* %CTOR7 }, { int, void ()* } { int 2147483647, void ()* null } ] @@ -20,6 +21,8 @@ %Y = global int -1 +%Z = global int 123 + %CTORGV = internal global bool false ;; Should become constant after eval implementation @@ -73,6 +76,16 @@ ret void } +internal void %CTOR7() { + call void %setto(int* %Z, int 0) + ret void +} + +void %setto(int* %P, int %V) { + store int %V, int* %P + ret void +} + bool %accessor() { %V = load bool* %CTORGV ;; constant true ret bool %V From lattner at cs.uiuc.edu Mon Sep 26 23:45:46 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 23:45:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200509270445.XAA15272@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.54 -> 1.55 --- Log message: Implement support for static constructors with calls in them. This is useful because gccas runs globalopt before inlining. This implements ctor-list-opt.ll:CTOR7 --- Diffs of the changes: (+54 -23) GlobalOpt.cpp | 77 ++++++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 54 insertions(+), 23 deletions(-) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.54 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.55 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.54 Mon Sep 26 23:27:01 2005 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 26 23:45:34 2005 @@ -1366,13 +1366,26 @@ /// EvaluateFunction - Evaluate a call to function F, returning true if /// successful, false if we can't evaluate it. ActualArgs contains the formal /// arguments for the function. -static bool EvaluateFunction(Function *F, +static bool EvaluateFunction(Function *F, Constant *&RetVal, const std::vector &ActualArgs, std::vector &CallStack, std::map &MutatedMemory, std::vector &AllocaTmps) { + // Check to see if this function is already executing (recursion). If so, + // bail out. TODO: we might want to accept limited recursion. + if (std::find(CallStack.begin(), CallStack.end(), F) != CallStack.end()) + return false; + + CallStack.push_back(F); + /// Values - As we compute SSA register values, we store their contents here. std::map Values; + + // Initialize arguments to the incoming values specified. + unsigned ArgNo = 0; + for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; + ++AI, ++ArgNo) + Values[AI] = ActualArgs[ArgNo]; /// ExecutedBlocks - We only handle non-looping, non-recursive code. As such, /// we can only evaluate any one basic block at most once. This set keeps @@ -1381,18 +1394,17 @@ // CurInst - The current instruction we're evaluating. BasicBlock::iterator CurInst = F->begin()->begin(); - ExecutedBlocks.insert(F->begin()); // This is the main evaluation loop. while (1) { Constant *InstResult = 0; if (StoreInst *SI = dyn_cast(CurInst)) { - if (SI->isVolatile()) break; // no volatile accesses. + if (SI->isVolatile()) return false; // no volatile accesses. Constant *Ptr = getVal(Values, SI->getOperand(1)); if (!isSimpleEnoughPointerToCommit(Ptr)) // If this is too complex for us to commit, reject it. - break; + return false; Constant *Val = getVal(Values, SI->getOperand(0)); MutatedMemory[Ptr] = Val; } else if (BinaryOperator *BO = dyn_cast(CurInst)) { @@ -1417,18 +1429,37 @@ GEPOps.push_back(getVal(Values, GEP->getOperand(i))); InstResult = ConstantExpr::getGetElementPtr(P, GEPOps); } else if (LoadInst *LI = dyn_cast(CurInst)) { - if (LI->isVolatile()) break; // no volatile accesses. + if (LI->isVolatile()) return false; // no volatile accesses. InstResult = ComputeLoadResult(getVal(Values, LI->getOperand(0)), MutatedMemory); - if (InstResult == 0) break; // Could not evaluate load. + if (InstResult == 0) return false; // Could not evaluate load. } else if (AllocaInst *AI = dyn_cast(CurInst)) { - if (AI->isArrayAllocation()) break; // Cannot handle array allocs. + if (AI->isArrayAllocation()) return false; // Cannot handle array allocs. const Type *Ty = AI->getType()->getElementType(); AllocaTmps.push_back(new GlobalVariable(Ty, false, GlobalValue::InternalLinkage, UndefValue::get(Ty), AI->getName())); - InstResult = AllocaTmps.back(); + InstResult = AllocaTmps.back(); + } else if (CallInst *CI = dyn_cast(CurInst)) { + // Resolve function pointers. + Function *Callee = dyn_cast(getVal(Values, CI->getOperand(0))); + if (!Callee) return false; // Cannot resolve. + + if (Callee->isExternal() || Callee->getFunctionType()->isVarArg()) { + return false; // TODO: Constant fold calls. + } + + std::vector Formals; + for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) + Formals.push_back(getVal(Values, CI->getOperand(i))); + Constant *RetVal; + + // Execute the call, if successful, use the return value. + if (!EvaluateFunction(Callee, RetVal, Formals, CallStack, + MutatedMemory, AllocaTmps)) + return false; + InstResult = RetVal; } else if (TerminatorInst *TI = dyn_cast(CurInst)) { BasicBlock *NewBB = 0; if (BranchInst *BI = dyn_cast(CurInst)) { @@ -1437,27 +1468,30 @@ } else { ConstantBool *Cond = dyn_cast(getVal(Values, BI->getCondition())); - if (!Cond) break; // Cannot determine. + if (!Cond) return false; // Cannot determine. NewBB = BI->getSuccessor(!Cond->getValue()); } } else if (SwitchInst *SI = dyn_cast(CurInst)) { ConstantInt *Val = dyn_cast(getVal(Values, SI->getCondition())); - if (!Val) break; // Cannot determine. + if (!Val) return false; // Cannot determine. NewBB = SI->getSuccessor(SI->findCaseValue(Val)); } else if (ReturnInst *RI = dyn_cast(CurInst)) { - assert(RI->getNumOperands() == 0); + if (RI->getNumOperands()) + RetVal = getVal(Values, RI->getOperand(0)); + + CallStack.pop_back(); // return from fn. return true; // We succeeded at evaluating this ctor! } else { - // unwind, unreachable. - break; // Cannot handle this terminator. + // invoke, unwind, unreachable. + return false; // Cannot handle this terminator. } // Okay, we succeeded in evaluating this control flow. See if we have - // executed the new block before. If so, we have a looping or recursive - // function, which we cannot evaluate in reasonable time. + // executed the new block before. If so, we have a looping function, + // which we cannot evaluate in reasonable time. if (!ExecutedBlocks.insert(NewBB).second) - break; // Recursed/looped! + return false; // looped! // Okay, we have never been in this block before. Check to see if there // are any PHI nodes. If so, evaluate them with information about where @@ -1471,10 +1505,8 @@ // Do NOT increment CurInst. We know that the terminator had no value. continue; } else { - // TODO: use ConstantFoldCall for function calls. - // Did not know how to evaluate this! - break; + return false; } if (!CurInst->use_empty()) @@ -1483,8 +1515,6 @@ // Advance program counter. ++CurInst; } - - return false; } /// EvaluateStaticConstructor - Evaluate static constructors in the function, if @@ -1506,8 +1536,9 @@ std::vector CallStack; // Call the function. - bool EvalSuccess = EvaluateFunction(F, std::vector(), CallStack, - MutatedMemory, AllocaTmps); + Constant *RetValDummy; + bool EvalSuccess = EvaluateFunction(F, RetValDummy, std::vector(), + CallStack, MutatedMemory, AllocaTmps); if (EvalSuccess) { // We succeeded at evaluation: commit the result. DEBUG(std::cerr << "FULLY EVALUATED GLOBAL CTOR FUNCTION '" << From lattner at cs.uiuc.edu Mon Sep 26 23:50:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 26 Sep 2005 23:50:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200509270450.XAA15338@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.55 -> 1.56 --- Log message: Fix a bug where we would evaluate stores into linkonce objects which could be potentially replaced at link-time. --- Diffs of the changes: (+6 -1) GlobalOpt.cpp | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.55 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.56 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.55 Mon Sep 26 23:45:34 2005 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 26 23:50:03 2005 @@ -1239,13 +1239,18 @@ /// we punt. We basically just support direct accesses to globals and GEP's of /// globals. This should be kept up to date with CommitValueTo. static bool isSimpleEnoughPointerToCommit(Constant *C) { - if (GlobalVariable *GV = dyn_cast(C)) + if (GlobalVariable *GV = dyn_cast(C)) { + if (!GV->hasExternalLinkage() && !GV->hasInternalLinkage()) + return false; // do not allow weak/linkonce linkage. return !GV->isExternal(); // reject external globals. + } if (ConstantExpr *CE = dyn_cast(C)) // Handle a constantexpr gep. if (CE->getOpcode() == Instruction::GetElementPtr && isa(CE->getOperand(0))) { GlobalVariable *GV = cast(CE->getOperand(0)); + if (!GV->hasExternalLinkage() && !GV->hasInternalLinkage()) + return false; // do not allow weak/linkonce linkage. return GV->hasInitializer() && ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE); } From lattner at cs.uiuc.edu Tue Sep 27 00:02:14 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 00:02:14 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll Message-ID: <200509270502.AAA15483@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/GlobalOpt: ctor-list-opt.ll updated: 1.7 -> 1.8 --- Log message: add a new testcase for constant foldable calls --- Diffs of the changes: (+10 -4) ctor-list-opt.ll | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) Index: llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll diff -u llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.7 llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.8 --- llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll:1.7 Mon Sep 26 23:44:04 2005 +++ llvm/test/Regression/Transforms/GlobalOpt/ctor-list-opt.ll Tue Sep 27 00:02:03 2005 @@ -1,7 +1,7 @@ ; RUN: llvm-as < %s | opt -globalopt -disable-output && ; RUN: llvm-as < %s | opt -globalopt | llvm-dis | not grep CTOR -%llvm.global_ctors = appending global [9 x { int, void ()* }] [ +%llvm.global_ctors = appending global [10 x { int, void ()* }] [ { int, void ()* } { int 65535, void ()* %CTOR1 }, { int, void ()* } { int 65535, void ()* %CTOR1 }, { int, void ()* } { int 65535, void ()* %CTOR2 }, @@ -10,18 +10,17 @@ { int, void ()* } { int 65535, void ()* %CTOR5 }, { int, void ()* } { int 65535, void ()* %CTOR6 }, { int, void ()* } { int 65535, void ()* %CTOR7 }, + { int, void ()* } { int 65535, void ()* %CTOR8 }, { int, void ()* } { int 2147483647, void ()* null } ] %G = global int 0 %G2 = global int 0 %G3 = global int -123 - %X = global {int, [2 x int]} { int 0, [2 x int] [ int 17, int 21] } - %Y = global int -1 - %Z = global int 123 +%D = global double 0.0 %CTORGV = internal global bool false ;; Should become constant after eval @@ -86,6 +85,13 @@ ret void } +declare double %cos(double) + +internal void %CTOR8() { + %X = call double %cos(double 1.0) + store double %X, double* %D + ret void +} bool %accessor() { %V = load bool* %CTORGV ;; constant true ret bool %V From lattner at cs.uiuc.edu Tue Sep 27 00:02:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 00:02:55 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200509270502.AAA15516@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.56 -> 1.57 --- Log message: Add support for external calls that we know how to constant fold. This implements ctor-list-opt.ll:CTOR8 --- Diffs of the changes: (+20 -11) GlobalOpt.cpp | 31 ++++++++++++++++++++----------- 1 files changed, 20 insertions(+), 11 deletions(-) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.56 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.57 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.56 Mon Sep 26 23:50:03 2005 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Tue Sep 27 00:02:43 2005 @@ -1450,21 +1450,30 @@ // Resolve function pointers. Function *Callee = dyn_cast(getVal(Values, CI->getOperand(0))); if (!Callee) return false; // Cannot resolve. - - if (Callee->isExternal() || Callee->getFunctionType()->isVarArg()) { - return false; // TODO: Constant fold calls. - } - + std::vector Formals; for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) Formals.push_back(getVal(Values, CI->getOperand(i))); - Constant *RetVal; - // Execute the call, if successful, use the return value. - if (!EvaluateFunction(Callee, RetVal, Formals, CallStack, - MutatedMemory, AllocaTmps)) - return false; - InstResult = RetVal; + if (Callee->isExternal()) { + // If this is a function we can constant fold, do it. + if (Constant *C = ConstantFoldCall(Callee, Formals)) { + InstResult = C; + } else { + return false; + } + } else { + if (Callee->getFunctionType()->isVarArg()) + return false; + + Constant *RetVal; + + // Execute the call, if successful, use the return value. + if (!EvaluateFunction(Callee, RetVal, Formals, CallStack, + MutatedMemory, AllocaTmps)) + return false; + InstResult = RetVal; + } } else if (TerminatorInst *TI = dyn_cast(CurInst)) { BasicBlock *NewBB = 0; if (BranchInst *BI = dyn_cast(CurInst)) { From lattner at cs.uiuc.edu Tue Sep 27 01:08:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 01:08:44 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Constant.h Constants.h Value.h Message-ID: <200509270608.BAA15768@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constant.h updated: 1.23 -> 1.24 Constants.h updated: 1.73 -> 1.74 Value.h updated: 1.77 -> 1.78 --- Log message: Split SimpleConstantVal up into its components, so each Constant subclass gets a different enum value. This allows 'classof' for these to be really simple, not needing to call getType() anymore. This speeds up isa/dyncast/etc for constants, and also makes them smaller. For example, the text section of a release build of InstCombine.cpp shrinks from 230037 bytes to 216363 bytes, a 6% reduction. --- Diffs of the changes: (+32 -35) Constant.h | 8 ++------ Constants.h | 38 ++++++++++++++++---------------------- Value.h | 21 ++++++++++++++------- 3 files changed, 32 insertions(+), 35 deletions(-) Index: llvm/include/llvm/Constant.h diff -u llvm/include/llvm/Constant.h:1.23 llvm/include/llvm/Constant.h:1.24 --- llvm/include/llvm/Constant.h:1.23 Thu Apr 21 15:11:51 2005 +++ llvm/include/llvm/Constant.h Tue Sep 27 01:08:32 2005 @@ -61,12 +61,8 @@ static inline bool classof(const Constant *) { return true; } static inline bool classof(const GlobalValue *) { return true; } static inline bool classof(const Value *V) { - return V->getValueType() == Value::SimpleConstantVal || - V->getValueType() == Value::ConstantExprVal || - V->getValueType() == Value::ConstantAggregateZeroVal || - V->getValueType() == Value::FunctionVal || - V->getValueType() == Value::GlobalVariableVal || - V->getValueType() == Value::UndefValueVal; + return V->getValueType() >= ConstantFirstVal && + V->getValueType() <= ConstantLastVal; } /// replaceUsesOfWithOnConstant - This method is a special form of Index: llvm/include/llvm/Constants.h diff -u llvm/include/llvm/Constants.h:1.73 llvm/include/llvm/Constants.h:1.74 --- llvm/include/llvm/Constants.h:1.73 Sat Sep 24 17:57:28 2005 +++ llvm/include/llvm/Constants.h Tue Sep 27 01:08:32 2005 @@ -47,7 +47,7 @@ int64_t Signed; uint64_t Unsigned; } Val; - ConstantIntegral(const Type *Ty, uint64_t V); + ConstantIntegral(const Type *Ty, ValueTy VT, uint64_t V); public: /// getRawValue - return the underlying value of this constant as a 64-bit @@ -98,8 +98,9 @@ /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantIntegral *) { return true; } static bool classof(const Value *V) { - return V->getValueType() == SimpleConstantVal && - V->getType()->isIntegral(); + return V->getValueType() == ConstantBoolVal || + V->getValueType() == ConstantSIntVal || + V->getValueType() == ConstantUIntVal; } }; @@ -134,7 +135,7 @@ /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantBool *) { return true; } static bool classof(const Value *V) { - return (V == True) | (V == False); + return V->getValueType() == ConstantBoolVal; } }; @@ -146,7 +147,7 @@ class ConstantInt : public ConstantIntegral { protected: ConstantInt(const ConstantInt &); // DO NOT IMPLEMENT - ConstantInt(const Type *Ty, uint64_t V); + ConstantInt(const Type *Ty, ValueTy VT, uint64_t V); public: /// equalsInt - Provide a helper method that can be used to determine if the /// constant contained within is equal to a constant. This only works for @@ -173,8 +174,8 @@ /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantInt *) { return true; } static bool classof(const Value *V) { - return V->getValueType() == SimpleConstantVal && - V->getType()->isInteger(); + return V->getValueType() == ConstantSIntVal || + V->getValueType() == ConstantUIntVal; } }; @@ -227,8 +228,7 @@ /// static inline bool classof(const ConstantSInt *) { return true; } static bool classof(const Value *V) { - return V->getValueType() == SimpleConstantVal && - V->getType()->isSigned(); + return V->getValueType() == ConstantSIntVal; } }; @@ -263,8 +263,7 @@ /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantUInt *) { return true; } static bool classof(const Value *V) { - return V->getValueType() == SimpleConstantVal && - V->getType()->isUnsigned(); + return V->getValueType() == ConstantUIntVal; } }; @@ -301,8 +300,7 @@ /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantFP *) { return true; } static bool classof(const Value *V) { - return V->getValueType() == SimpleConstantVal && - V->getType()->isFloatingPoint(); + return V->getValueType() == ConstantFPVal; } }; @@ -380,8 +378,7 @@ /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantArray *) { return true; } static bool classof(const Value *V) { - return V->getValueType() == SimpleConstantVal && - V->getType()->getTypeID() == Type::ArrayTyID; + return V->getValueType() == ConstantArrayVal; } }; @@ -422,8 +419,7 @@ /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantStruct *) { return true; } static bool classof(const Value *V) { - return V->getValueType() == SimpleConstantVal && - V->getType()->getTypeID() == Type::StructTyID; + return V->getValueType() == ConstantStructVal; } }; @@ -461,8 +457,7 @@ /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantPacked *) { return true; } static bool classof(const Value *V) { - return V->getValueType() == SimpleConstantVal && - V->getType()->getTypeID() == Type::PackedTyID; + return V->getValueType() == ConstantPackedVal; } }; @@ -475,7 +470,7 @@ protected: ConstantPointerNull(const PointerType *T) : Constant(reinterpret_cast(T), - Value::SimpleConstantVal, 0, 0) {} + Value::ConstantPointerNullVal, 0, 0) {} public: @@ -498,8 +493,7 @@ /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantPointerNull *) { return true; } static bool classof(const Value *V) { - return V->getValueType() == SimpleConstantVal && - isa(V->getType()); + return V->getValueType() == ConstantPointerNullVal; } }; Index: llvm/include/llvm/Value.h diff -u llvm/include/llvm/Value.h:1.77 llvm/include/llvm/Value.h:1.78 --- llvm/include/llvm/Value.h:1.77 Tue Aug 16 17:04:58 2005 +++ llvm/include/llvm/Value.h Tue Sep 27 01:08:32 2005 @@ -146,8 +146,19 @@ UndefValueVal, // This is an instance of UndefValue ConstantExprVal, // This is an instance of ConstantExpr ConstantAggregateZeroVal, // This is an instance of ConstantAggregateNull - SimpleConstantVal, // This is some other type of Constant + ConstantBoolVal, // This is an instance of ConstantBool + ConstantSIntVal, // This is an instance of ConstantSInt + ConstantUIntVal, // This is an instance of ConstantUInt + ConstantFPVal, // This is an instance of ConstantFP + ConstantArrayVal, // This is an instance of ConstantArray + ConstantStructVal, // This is an instance of ConstantStruct + ConstantPackedVal, // This is an instance of ConstantPacked + ConstantPointerNullVal, // This is an instance of ConstantPointerNull InstructionVal, // This is an instance of Instruction + + // Markers: + ConstantFirstVal = FunctionVal, + ConstantLastVal = ConstantPointerNullVal, }; unsigned getValueType() const { return SubclassID; @@ -194,12 +205,8 @@ // the subtype header files to test to see if the value is a subclass... // template <> inline bool isa_impl(const Value &Val) { - return Val.getValueType() == Value::SimpleConstantVal || - Val.getValueType() == Value::FunctionVal || - Val.getValueType() == Value::GlobalVariableVal || - Val.getValueType() == Value::ConstantExprVal || - Val.getValueType() == Value::ConstantAggregateZeroVal || - Val.getValueType() == Value::UndefValueVal; + return Val.getValueType() >= Value::ConstantFirstVal && + Val.getValueType() <= Value::ConstantLastVal; } template <> inline bool isa_impl(const Value &Val) { return Val.getValueType() == Value::ArgumentVal; From lattner at cs.uiuc.edu Tue Sep 27 01:09:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 01:09:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200509270609.BAA15826@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.128 -> 1.129 --- Log message: Split SimpleConstantVal up into its components, so each Constant subclass getsa different enum value. This allows 'classof' for these to be really simple,not needing to call getType() anymore. This speeds up isa/dyncast/etc for constants, and also makes them smaller. For example, the text section of a release build of InstCombine.cpp shrinks from 230037 bytes to 216363 bytes, a 6% reduction. --- Diffs of the changes: (+14 -10) Constants.cpp | 24 ++++++++++++++---------- 1 files changed, 14 insertions(+), 10 deletions(-) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.128 llvm/lib/VMCore/Constants.cpp:1.129 --- llvm/lib/VMCore/Constants.cpp:1.128 Wed Aug 17 15:06:22 2005 +++ llvm/lib/VMCore/Constants.cpp Tue Sep 27 01:09:08 2005 @@ -209,38 +209,42 @@ //===----------------------------------------------------------------------===// // Normal Constructors -ConstantIntegral::ConstantIntegral(const Type *Ty, uint64_t V) - : Constant(Ty, SimpleConstantVal, 0, 0) { +ConstantIntegral::ConstantIntegral(const Type *Ty, ValueTy VT, uint64_t V) + : Constant(Ty, VT, 0, 0) { Val.Unsigned = V; } -ConstantBool::ConstantBool(bool V) : ConstantIntegral(Type::BoolTy, V) { +ConstantBool::ConstantBool(bool V) + : ConstantIntegral(Type::BoolTy, ConstantBoolVal, V) { } -ConstantInt::ConstantInt(const Type *Ty, uint64_t V) : ConstantIntegral(Ty, V) { +ConstantInt::ConstantInt(const Type *Ty, ValueTy VT, uint64_t V) + : ConstantIntegral(Ty, VT, V) { } -ConstantSInt::ConstantSInt(const Type *Ty, int64_t V) : ConstantInt(Ty, V) { +ConstantSInt::ConstantSInt(const Type *Ty, int64_t V) + : ConstantInt(Ty, ConstantSIntVal, V) { assert(Ty->isInteger() && Ty->isSigned() && "Illegal type for signed integer constant!"); assert(isValueValidForType(Ty, V) && "Value too large for type!"); } -ConstantUInt::ConstantUInt(const Type *Ty, uint64_t V) : ConstantInt(Ty, V) { +ConstantUInt::ConstantUInt(const Type *Ty, uint64_t V) + : ConstantInt(Ty, ConstantUIntVal, V) { assert(Ty->isInteger() && Ty->isUnsigned() && "Illegal type for unsigned integer constant!"); assert(isValueValidForType(Ty, V) && "Value too large for type!"); } ConstantFP::ConstantFP(const Type *Ty, double V) - : Constant(Ty, SimpleConstantVal, 0, 0) { + : Constant(Ty, ConstantFPVal, 0, 0) { assert(isValueValidForType(Ty, V) && "Value too large for type!"); Val = V; } ConstantArray::ConstantArray(const ArrayType *T, const std::vector &V) - : Constant(T, SimpleConstantVal, new Use[V.size()], V.size()) { + : Constant(T, ConstantArrayVal, new Use[V.size()], V.size()) { assert(V.size() == T->getNumElements() && "Invalid initializer vector for constant array"); Use *OL = OperandList; @@ -259,7 +263,7 @@ ConstantStruct::ConstantStruct(const StructType *T, const std::vector &V) - : Constant(T, SimpleConstantVal, new Use[V.size()], V.size()) { + : Constant(T, ConstantStructVal, new Use[V.size()], V.size()) { assert(V.size() == T->getNumElements() && "Invalid initializer vector for constant structure"); Use *OL = OperandList; @@ -280,7 +284,7 @@ ConstantPacked::ConstantPacked(const PackedType *T, const std::vector &V) - : Constant(T, SimpleConstantVal, new Use[V.size()], V.size()) { + : Constant(T, ConstantPackedVal, new Use[V.size()], V.size()) { Use *OL = OperandList; for (unsigned i = 0, e = V.size(); i != e; ++i) { assert((V[i]->getType() == T->getElementType() || From lattner at cs.uiuc.edu Tue Sep 27 01:38:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 01:38:16 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/PatternMatch.h Message-ID: <200509270638.BAA15972@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: PatternMatch.h updated: 1.5 -> 1.6 --- Log message: Make this slightly more efficient by pushing actual type information down into the evaluator. This shrinks a release build of instcombine's text section from 216363 to 215975 bytes (on PPC). --- Diffs of the changes: (+11 -8) PatternMatch.h | 19 +++++++++++-------- 1 files changed, 11 insertions(+), 8 deletions(-) Index: llvm/include/llvm/Support/PatternMatch.h diff -u llvm/include/llvm/Support/PatternMatch.h:1.5 llvm/include/llvm/Support/PatternMatch.h:1.6 --- llvm/include/llvm/Support/PatternMatch.h:1.5 Thu Apr 21 15:44:59 2005 +++ llvm/include/llvm/Support/PatternMatch.h Tue Sep 27 01:38:05 2005 @@ -71,7 +71,8 @@ // Matchers for specific binary operators // -template +template struct BinaryOp_match { LHS_t L; RHS_t R; @@ -80,9 +81,11 @@ template bool match(OpTy *V) { - if (Instruction *I = dyn_cast(V)) + if (V->getValueType() == Value::InstructionVal + Opcode) { + ConcreteTy *I = cast(V); return I->getOpcode() == Opcode && L.match(I->getOperand(0)) && R.match(I->getOperand(1)); + } if (ConstantExpr *CE = dyn_cast(V)) return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) && R.match(CE->getOperand(1)); @@ -139,15 +142,15 @@ } template -inline BinaryOp_match m_Shl(const LHS &L, - const RHS &R) { - return BinaryOp_match(L, R); +inline BinaryOp_match m_Shl(const LHS &L, const RHS &R) { + return BinaryOp_match(L, R); } template -inline BinaryOp_match m_Shr(const LHS &L, - const RHS &R) { - return BinaryOp_match(L, R); +inline BinaryOp_match m_Shr(const LHS &L, const RHS &R) { + return BinaryOp_match(L, R); } //===----------------------------------------------------------------------===// From jlaskey at apple.com Tue Sep 27 12:32:56 2005 From: jlaskey at apple.com (Jim Laskey) Date: Tue, 27 Sep 2005 12:32:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200509271732.MAA17503@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.23 -> 1.24 --- Log message: Remove some redundancies. --- Diffs of the changes: (+10 -10) ScheduleDAG.cpp | 20 ++++++++++---------- 1 files changed, 10 insertions(+), 10 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.23 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.24 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.23 Mon Sep 26 16:57:04 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Tue Sep 27 12:32:45 2005 @@ -197,7 +197,6 @@ SDOperand Op; // Operand information unsigned Latency; // Cycles to complete instruction unsigned ResourceSet; // Bit vector of usable resources - bool IsBoundary; // Do not shift passed this instruction. unsigned Slot; // Operand's time slot // Ctor. @@ -205,7 +204,6 @@ : Op(op) , Latency(0) , ResourceSet(0) - , IsBoundary(false) , Slot(0) {} }; @@ -452,10 +450,10 @@ MachineOpCode TOpc = Op.getTargetOpcode(); // FIXME SI->Latency = std::max(1, TII.maxLatency(TOpc)); // FIXME SI->ResourceSet = TII.resources(TOpc); - // There is a cost for keeping values across a call. - SI->IsBoundary = TII.isCall(TOpc); - - if (TII.isLoad(TOpc)) { + if (TII.isCall(TOpc)) { + SI->ResourceSet = RSInteger; + SI->Latency = 40; + } else if (TII.isLoad(TOpc)) { SI->ResourceSet = RSLoadStore; SI->Latency = 5; } else if (TII.isStore(TOpc)) { @@ -526,7 +524,11 @@ /// conflict with operands of B. bool SimpleSched::isWeakDependency(SDNode *A, SDNode *B) { // TODO check for conflicting real registers and aliases +#if 0 // Since we are in SSA form and not checking register aliasing return A->getOpcode() == ISD::EntryToken || isStrongDependency(B, A); +#else + return A->getOpcode() == ISD::EntryToken; +#endif } /// ScheduleBackward - Schedule instructions so that any long latency @@ -554,8 +556,7 @@ if (isStrongDependency(SI->Op, Other->Op)) { Slot = Other->Slot + Other->Latency; break; - } else if (SI->IsBoundary || Other->IsBoundary || - isWeakDependency(SI->Op, Other->Op)) { + } else if (isWeakDependency(SI->Op, Other->Op)) { Slot = Other->Slot; break; } @@ -609,8 +610,7 @@ if (isStrongDependency(Other->Op, SI->Op)) { Slot = Other->Slot + Other->Latency; break; - } else if (SI->IsBoundary || Other->IsBoundary || - isWeakDependency(Other->Op, SI->Op)) { + } else if (isWeakDependency(Other->Op, SI->Op)) { Slot = Other->Slot; break; } From lattner at cs.uiuc.edu Tue Sep 27 12:45:45 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 12:45:45 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509271745.MAA17831@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.77 -> 1.78 --- Log message: Make sure to clear the CodeGenMap after each basic block is selected to avoid cross MBB pollution. --- Diffs of the changes: (+1 -0) PPC32ISelDAGToDAG.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.77 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.78 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.77 Tue Sep 13 17:05:21 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Tue Sep 27 12:45:33 2005 @@ -87,6 +87,7 @@ DEBUG(BB->dump()); // Select target instructions for the DAG. DAG.setRoot(Select(DAG.getRoot())); + CodeGenMap.clear(); DAG.RemoveDeadNodes(); // Emit machine code to BB. From lattner at cs.uiuc.edu Tue Sep 27 13:34:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 13:34:42 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LowerInvoke/basictest.ll Message-ID: <200509271834.NAA18268@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LowerInvoke: basictest.ll added (r1.1) --- Log message: Add a simple testcase for lowerinvoke --- Diffs of the changes: (+28 -0) basictest.ll | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+) Index: llvm/test/Regression/Transforms/LowerInvoke/basictest.ll diff -c /dev/null llvm/test/Regression/Transforms/LowerInvoke/basictest.ll:1.1 *** /dev/null Tue Sep 27 13:34:41 2005 --- llvm/test/Regression/Transforms/LowerInvoke/basictest.ll Tue Sep 27 13:34:31 2005 *************** *** 0 **** --- 1,28 ---- + ; RUN: llvm-as < %s | opt -lowerinvoke -disable-output && + ; RUN: llvm-as < %s | opt -lowerinvoke -disable-output -enable-correct-eh-support + + implementation + + int %foo() { + invoke int %foo() to label %Ok unwind label %Crap + Ok: + invoke int %foo() to label %Ok2 unwind label %Crap + Ok2: + ret int 2 + Crap: + ret int 1 + } + + int %bar(int %blah) { + br label %doit + doit: + ;; Value live across an unwind edge. + %B2 = add int %blah, 1 + invoke int %foo() to label %Ok unwind label %Crap + Ok: + invoke int %foo() to label %Ok2 unwind label %Crap + Ok2: + ret int 2 + Crap: + ret int %B2 + } From lattner at cs.uiuc.edu Tue Sep 27 14:38:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 14:38:55 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/Local.h Message-ID: <200509271938.OAA18891@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: Local.h updated: 1.20 -> 1.21 --- Log message: allow demotion to volatile values --- Diffs of the changes: (+1 -1) Local.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Transforms/Utils/Local.h diff -u llvm/include/llvm/Transforms/Utils/Local.h:1.20 llvm/include/llvm/Transforms/Utils/Local.h:1.21 --- llvm/include/llvm/Transforms/Utils/Local.h:1.20 Mon Sep 26 00:26:32 2005 +++ llvm/include/llvm/Transforms/Utils/Local.h Tue Sep 27 14:38:43 2005 @@ -98,7 +98,7 @@ /// invalidating the SSA information for the value. It returns the pointer to /// the alloca inserted to create a stack slot for X. /// -AllocaInst *DemoteRegToStack(Instruction &X); +AllocaInst *DemoteRegToStack(Instruction &X, bool VolatileLoads = false); } // End llvm namespace From lattner at cs.uiuc.edu Tue Sep 27 14:39:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 14:39:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/DemoteRegToStack.cpp Message-ID: <200509271939.OAA18901@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: DemoteRegToStack.cpp updated: 1.13 -> 1.14 --- Log message: allow demotion to volatile values, add support for invoke --- Diffs of the changes: (+15 -12) DemoteRegToStack.cpp | 27 +++++++++++++++------------ 1 files changed, 15 insertions(+), 12 deletions(-) Index: llvm/lib/Transforms/Utils/DemoteRegToStack.cpp diff -u llvm/lib/Transforms/Utils/DemoteRegToStack.cpp:1.13 llvm/lib/Transforms/Utils/DemoteRegToStack.cpp:1.14 --- llvm/lib/Transforms/Utils/DemoteRegToStack.cpp:1.13 Thu Apr 21 18:45:34 2005 +++ llvm/lib/Transforms/Utils/DemoteRegToStack.cpp Tue Sep 27 14:39:00 2005 @@ -29,7 +29,7 @@ /// invalidating the SSA information for the value. It returns the pointer to /// the alloca inserted to create a stack slot for I. /// -AllocaInst* llvm::DemoteRegToStack(Instruction &I) { +AllocaInst* llvm::DemoteRegToStack(Instruction &I, bool VolatileLoads) { if (I.use_empty()) return 0; // nothing to do! // Create a stack slot to hold the value. @@ -57,7 +57,7 @@ Value *&V = Loads[PN->getIncomingBlock(i)]; if (V == 0) { // Insert the load into the predecessor block - V = new LoadInst(Slot, I.getName()+".reload", + V = new LoadInst(Slot, I.getName()+".reload", VolatileLoads, PN->getIncomingBlock(i)->getTerminator()); } PN->setIncomingValue(i, V); @@ -65,7 +65,7 @@ } else { // If this is a normal instruction, just insert a load. - Value *V = new LoadInst(Slot, I.getName()+".reload", U); + Value *V = new LoadInst(Slot, I.getName()+".reload", VolatileLoads, U); U->replaceUsesOfWith(&I, V); } } @@ -74,18 +74,21 @@ // Insert stores of the computed value into the stack slot. We have to be // careful is I is an invoke instruction though, because we can't insert the // store AFTER the terminator instruction. + BasicBlock::iterator InsertPt; if (!isa(I)) { - BasicBlock::iterator InsertPt = &I; - for (++InsertPt; isa(InsertPt); ++InsertPt) - /* empty */; // Don't insert before any PHI nodes. - new StoreInst(&I, Slot, InsertPt); + InsertPt = &I; } else { - // FIXME: We cannot yet demote invoke instructions to the stack, because - // doing so would require breaking critical edges. This should be fixed - // eventually. - assert(0 && - "Cannot demote the value computed by an invoke instruction yet!"); + // We cannot demote invoke instructions to the stack if their normal edge + // is critical. + InvokeInst &II = cast(I); + assert(II.getNormalDest()->getSinglePredecessor() && + "Cannot demote invoke with a critical successor!"); + InsertPt = II.getNormalDest()->begin(); } + for (++InsertPt; isa(InsertPt); ++InsertPt) + /* empty */; // Don't insert before any PHI nodes. + new StoreInst(&I, Slot, InsertPt); + return Slot; } From lattner at cs.uiuc.edu Tue Sep 27 15:52:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 15:52:41 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/CBackend/2005-09-27-VolatileFuncPtr.ll Message-ID: <200509272052.PAA19668@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/CBackend: 2005-09-27-VolatileFuncPtr.ll added (r1.1) --- Log message: new testcase the CBE creates invalid C code for --- Diffs of the changes: (+10 -0) 2005-09-27-VolatileFuncPtr.ll | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/test/Regression/CodeGen/CBackend/2005-09-27-VolatileFuncPtr.ll diff -c /dev/null llvm/test/Regression/CodeGen/CBackend/2005-09-27-VolatileFuncPtr.ll:1.1 *** /dev/null Tue Sep 27 15:52:40 2005 --- llvm/test/Regression/CodeGen/CBackend/2005-09-27-VolatileFuncPtr.ll Tue Sep 27 15:52:30 2005 *************** *** 0 **** --- 1,10 ---- + ; RUN: llvm-as < %s | llc -march=c && + ; RUN: llvm-as < %s | llc -march=c | grep '\* *volatile *\*' + + %G = external global void()* + + void %test() { + volatile store void()* %test, void()** %G + volatile load void()** %G + ret void + } From lattner at cs.uiuc.edu Tue Sep 27 15:52:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 15:52:55 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200509272052.PAA19699@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.244 -> 1.245 --- Log message: fix CBackend/2005-09-27-VolatileFuncPtr.ll --- Diffs of the changes: (+4 -4) Writer.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.244 llvm/lib/Target/CBackend/Writer.cpp:1.245 --- llvm/lib/Target/CBackend/Writer.cpp:1.244 Tue Aug 23 15:22:50 2005 +++ llvm/lib/Target/CBackend/Writer.cpp Tue Sep 27 15:52:44 2005 @@ -1683,8 +1683,8 @@ Out << '*'; if (I.isVolatile()) { Out << "(("; - printType(Out, I.getType()); - Out << " volatile*)"; + printType(Out, I.getType(), "volatile*"); + Out << ")"; } writeOperand(I.getOperand(0)); @@ -1697,8 +1697,8 @@ Out << '*'; if (I.isVolatile()) { Out << "(("; - printType(Out, I.getOperand(0)->getType()); - Out << " volatile*)"; + printType(Out, I.getOperand(0)->getType(), " volatile*"); + Out << ")"; } writeOperand(I.getPointerOperand()); if (I.isVolatile()) Out << ')'; From lattner at cs.uiuc.edu Tue Sep 27 16:10:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 16:10:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200509272110.QAA19865@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.58 -> 1.59 --- Log message: Make the pass name simpler --- Diffs of the changes: (+1 -1) LoopStrengthReduce.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.58 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.59 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.58 Mon Sep 12 21:09:55 2005 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue Sep 27 16:10:32 2005 @@ -152,7 +152,7 @@ void DeleteTriviallyDeadInstructions(std::set &Insts); }; RegisterOpt X("loop-reduce", - "Strength Reduce GEP Uses of Ind. Vars"); + "Loop Strength Reduction"); } FunctionPass *llvm::createLoopStrengthReducePass(unsigned MaxTargetAMSize) { From lattner at cs.uiuc.edu Tue Sep 27 16:18:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 16:18:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LowerInvoke.cpp Message-ID: <200509272118.QAA19941@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LowerInvoke.cpp updated: 1.28 -> 1.29 --- Log message: Completely rewrite 'correct' eh support. This changes how setjmp insertion is performed so it is only at most once per function that contains an invoke instead of once per invoke in the function. This patch has the following perks: 1. It fixes PR631: http://llvm.cs.uiuc.edu/PR631 , which complains about slowness. 2. If fixes PR240: http://llvm.cs.uiuc.edu/PR240 , which complains about non-volatile vars being live across setjmp/longjmps. 3. It improves (but does not fix) the jmpbuf alignment issue on itanium by not forcing the jmpbufs to always be 8-bytes off the alignment of the structure. 4. It speeds up 253.perlbmk from 338s to 13.70s (a 25x improvement!), making us now about 4% faster than GCC. Further improvements are also possible. --- Diffs of the changes: (+300 -139) LowerInvoke.cpp | 439 ++++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 300 insertions(+), 139 deletions(-) Index: llvm/lib/Transforms/Scalar/LowerInvoke.cpp diff -u llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.28 llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.29 --- llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.28 Wed Aug 3 13:51:44 2005 +++ llvm/lib/Transforms/Scalar/LowerInvoke.cpp Tue Sep 27 16:18:17 2005 @@ -41,13 +41,17 @@ #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/CommandLine.h" #include using namespace llvm; namespace { - Statistic<> NumLowered("lowerinvoke", "Number of invoke & unwinds replaced"); + Statistic<> NumInvokes("lowerinvoke", "Number of invokes replaced"); + Statistic<> NumUnwinds("lowerinvoke", "Number of unwinds replaced"); + Statistic<> NumSpilled("lowerinvoke", + "Number of registers live across unwind edges"); cl::opt ExpensiveEHSupport("enable-correct-eh-support", cl::desc("Make the -lowerinvoke pass insert expensive, but correct, EH code")); @@ -65,10 +69,14 @@ public: bool doInitialization(Module &M); bool runOnFunction(Function &F); + private: void createAbortMessage(); void writeAbortMessage(Instruction *IB); bool insertCheapEHSupport(Function &F); + void splitLiveRangesLiveAcrossInvokes(std::vector &Invokes); + void rewriteExpensiveInvoke(InvokeInst *II, unsigned InvokeNo, + AllocaInst *InvokeNum, SwitchInst *CatchSwitch); bool insertExpensiveEHSupport(Function &F); }; @@ -97,9 +105,9 @@ { // The type is recursive, so use a type holder. std::vector Elements; + Elements.push_back(JmpBufTy); OpaqueType *OT = OpaqueType::get(); Elements.push_back(PointerType::get(OT)); - Elements.push_back(JmpBufTy); PATypeHolder JBLType(StructType::get(Elements)); OT->refineAbstractTypeTo(JBLType.get()); // Complete the cycle. JBLinkTy = JBLType.get(); @@ -220,7 +228,7 @@ // Remove the invoke instruction now. BB->getInstList().erase(II); - ++NumLowered; Changed = true; + ++NumInvokes; Changed = true; } else if (UnwindInst *UI = dyn_cast(BB->getTerminator())) { // Insert a new call to write(2, AbortMessage, AbortMessageLength); writeAbortMessage(UI); @@ -236,163 +244,316 @@ // Remove the unwind instruction now. BB->getInstList().erase(UI); - ++NumLowered; Changed = true; + ++NumUnwinds; Changed = true; } return Changed; } -bool LowerInvoke::insertExpensiveEHSupport(Function &F) { - bool Changed = false; - - // If a function uses invoke, we have an alloca for the jump buffer. - AllocaInst *JmpBuf = 0; +/// rewriteExpensiveInvoke - Insert code and hack the function to replace the +/// specified invoke instruction with a call. +void LowerInvoke::rewriteExpensiveInvoke(InvokeInst *II, unsigned InvokeNo, + AllocaInst *InvokeNum, + SwitchInst *CatchSwitch) { + ConstantUInt *InvokeNoC = ConstantUInt::get(Type::UIntTy, InvokeNo); + + // Insert a store of the invoke num before the invoke and store zero into the + // location afterward. + new StoreInst(InvokeNoC, InvokeNum, true, II); // volatile + new StoreInst(Constant::getNullValue(Type::UIntTy), InvokeNum, false, + II->getNormalDest()->begin()); // nonvolatile. + + // Add a switch case to our unwind block. + CatchSwitch->addCase(InvokeNoC, II->getUnwindDest()); + + // Insert a normal call instruction. + std::string Name = II->getName(); II->setName(""); + CallInst *NewCall = new CallInst(II->getCalledValue(), + std::vector(II->op_begin()+3, + II->op_end()), Name, + II); + NewCall->setCallingConv(II->getCallingConv()); + II->replaceAllUsesWith(NewCall); + + // Replace the invoke with an uncond branch. + new BranchInst(II->getNormalDest(), NewCall->getParent()); + II->eraseFromParent(); +} - // If this function contains an unwind instruction, two blocks get added: one - // to actually perform the longjmp, and one to terminate the program if there - // is no handler. - BasicBlock *UnwindBlock = 0, *TermBlock = 0; - std::vector JBPtrs; +/// MarkBlocksLiveIn - Insert BB and all of its predescessors into LiveBBs until +/// we reach blocks we've already seen. +static void MarkBlocksLiveIn(BasicBlock *BB, std::set &LiveBBs) { + if (!LiveBBs.insert(BB).second) return; // already been here. + + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) + MarkBlocksLiveIn(*PI, LiveBBs); +} - for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) - if (InvokeInst *II = dyn_cast(BB->getTerminator())) { - if (JmpBuf == 0) - JmpBuf = new AllocaInst(JBLinkTy, 0, "jblink", F.begin()->begin()); +// First thing we need to do is scan the whole function for values that are +// live across unwind edges. Each value that is live across an unwind edge +// we spill into a stack location, guaranteeing that there is nothing live +// across the unwind edge. This process also splits all critical edges +// coming out of invoke's. +void LowerInvoke:: +splitLiveRangesLiveAcrossInvokes(std::vector &Invokes) { + // First step, split all critical edges from invoke instructions. + for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { + InvokeInst *II = Invokes[i]; + SplitCriticalEdge(II, 0, this); + SplitCriticalEdge(II, 1, this); + assert(!isa(II->getNormalDest()) && + !isa(II->getUnwindDest()) && + "critical edge splitting left single entry phi nodes?"); + } - // On the entry to the invoke, we must install our JmpBuf as the top of - // the stack. - LoadInst *OldEntry = new LoadInst(JBListHead, "oldehlist", II); - - // Store this old value as our 'next' field, and store our alloca as the - // current jblist. - std::vector Idx; - Idx.push_back(Constant::getNullValue(Type::IntTy)); - Idx.push_back(ConstantUInt::get(Type::UIntTy, 0)); - Value *NextFieldPtr = new GetElementPtrInst(JmpBuf, Idx, "NextField", II); - new StoreInst(OldEntry, NextFieldPtr, II); - new StoreInst(JmpBuf, JBListHead, II); - - // Call setjmp, passing in the address of the jmpbuffer. - Idx[1] = ConstantUInt::get(Type::UIntTy, 1); - Value *JmpBufPtr = new GetElementPtrInst(JmpBuf, Idx, "TheJmpBuf", II); - Value *SJRet = new CallInst(SetJmpFn, JmpBufPtr, "sjret", II); - - // Compare the return value to zero. - Value *IsNormal = BinaryOperator::create(Instruction::SetEQ, SJRet, - Constant::getNullValue(SJRet->getType()), - "notunwind", II); - // Create the receiver block if there is a critical edge to the normal - // destination. - SplitCriticalEdge(II, 0, this); + Function *F = Invokes.back()->getParent()->getParent(); + + // To avoid having to handle incoming arguments specially, we lower each arg + // to a copy instruction in the entry block. This ensure that the argument + // value itself cannot be live across the entry block. + BasicBlock::iterator AfterAllocaInsertPt = F->begin()->begin(); + while (isa(AfterAllocaInsertPt) && + isa(cast(AfterAllocaInsertPt)->getArraySize())) + ++AfterAllocaInsertPt; + for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); + AI != E; ++AI) { + CastInst *NC = new CastInst(AI, AI->getType(), AI->getName()+".tmp", + AfterAllocaInsertPt); + AI->replaceAllUsesWith(NC); + NC->setOperand(0, AI); + } + + // Finally, scan the code looking for instructions with bad live ranges. + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) + for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ++II) { + // Ignore obvious cases we don't have to handle. In particular, most + // instructions either have no uses or only have a single use inside the + // current block. Ignore them quickly. + Instruction *Inst = II; + if (Inst->use_empty()) continue; + if (Inst->hasOneUse() && + cast(Inst->use_back())->getParent() == BB && + !isa(Inst->use_back())) continue; - // There should not be any PHI nodes in II->getNormalDest() now. It has - // a single predecessor, so any PHI nodes are unneeded. Remove them now - // by replacing them with their single input value. - assert(II->getNormalDest()->getSinglePredecessor() && - "Split crit edge doesn't have a single predecessor!"); - - BasicBlock::iterator InsertLoc = II->getNormalDest()->begin(); - while (PHINode *PN = dyn_cast(InsertLoc)) { - PN->replaceAllUsesWith(PN->getIncomingValue(0)); - PN->eraseFromParent(); - InsertLoc = II->getNormalDest()->begin(); + // Avoid iterator invalidation by copying users to a temporary vector. + std::vector Users; + for (Value::use_iterator UI = Inst->use_begin(), E = Inst->use_end(); + UI != E; ++UI) { + Instruction *User = cast(*UI); + if (User->getParent() != BB || isa(User)) + Users.push_back(User); } - - // Insert a normal call instruction on the normal execution path. - std::string Name = II->getName(); II->setName(""); - CallInst *NewCall = new CallInst(II->getCalledValue(), - std::vector(II->op_begin()+3, - II->op_end()), Name, - InsertLoc); - NewCall->setCallingConv(II->getCallingConv()); - II->replaceAllUsesWith(NewCall); - // If we got this far, then no exception was thrown and we can pop our - // jmpbuf entry off. - new StoreInst(OldEntry, JBListHead, InsertLoc); - - // Now we change the invoke into a branch instruction. - new BranchInst(II->getNormalDest(), II->getUnwindDest(), IsNormal, II); - - // Remove the InvokeInst now. - BB->getInstList().erase(II); - ++NumLowered; Changed = true; - - } else if (UnwindInst *UI = dyn_cast(BB->getTerminator())) { - if (UnwindBlock == 0) { - // Create two new blocks, the unwind block and the terminate block. Add - // them at the end of the function because they are not hot. - UnwindBlock = new BasicBlock("unwind", &F); - TermBlock = new BasicBlock("unwinderror", &F); - - // Insert return instructions. These really should be "barrier"s, as - // they are unreachable. - new ReturnInst(F.getReturnType() == Type::VoidTy ? 0 : - Constant::getNullValue(F.getReturnType()), UnwindBlock); - new ReturnInst(F.getReturnType() == Type::VoidTy ? 0 : - Constant::getNullValue(F.getReturnType()), TermBlock); + // Scan all of the uses and see if the live range is live across an unwind + // edge. If we find a use live across an invoke edge, create an alloca + // and spill the value. + AllocaInst *SpillLoc = 0; + std::set InvokesWithStoreInserted; + + // Find all of the blocks that this value is live in. + std::set LiveBBs; + LiveBBs.insert(Inst->getParent()); + while (!Users.empty()) { + Instruction *U = Users.back(); + Users.pop_back(); + + BasicBlock *UseBlock; + if (!isa(U)) { + MarkBlocksLiveIn(U->getParent(), LiveBBs); + } else { + // Uses for a PHI node occur in their predecessor block. + PHINode *PN = cast(U); + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + if (PN->getIncomingValue(i) == Inst) + MarkBlocksLiveIn(PN->getIncomingBlock(i), LiveBBs); + } + } + + // Now that we know all of the blocks that this thing is live in, see if + // it includes any of the unwind locations. + bool NeedsSpill = false; + for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { + BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest(); + if (UnwindBlock != BB && LiveBBs.count(UnwindBlock)) { + NeedsSpill = true; + } } - // Load the JBList, if it's null, then there was no catch! - LoadInst *Ptr = new LoadInst(JBListHead, "ehlist", UI); - Value *NotNull = BinaryOperator::create(Instruction::SetNE, Ptr, - Constant::getNullValue(Ptr->getType()), - "notnull", UI); - new BranchInst(UnwindBlock, TermBlock, NotNull, UI); + // If we decided we need a spill, do it. + if (NeedsSpill) { + ++NumSpilled; + DemoteRegToStack(*Inst, true); + } + } +} - // Remember the loaded value so we can insert the PHI node as needed. - JBPtrs.push_back(Ptr); +bool LowerInvoke::insertExpensiveEHSupport(Function &F) { + std::vector Returns; + std::vector Unwinds; + std::vector Invokes; - // Remove the UnwindInst now. - BB->getInstList().erase(UI); - ++NumLowered; Changed = true; + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + if (ReturnInst *RI = dyn_cast(BB->getTerminator())) { + // Remember all return instructions in case we insert an invoke into this + // function. + Returns.push_back(RI); + } else if (InvokeInst *II = dyn_cast(BB->getTerminator())) { + Invokes.push_back(II); + } else if (UnwindInst *UI = dyn_cast(BB->getTerminator())) { + Unwinds.push_back(UI); } - // If an unwind instruction was inserted, we need to set up the Unwind and - // term blocks. - if (UnwindBlock) { - // In the unwind block, we know that the pointer coming in on the JBPtrs - // list are non-null. - Instruction *RI = UnwindBlock->getTerminator(); - - Value *RecPtr; - if (JBPtrs.size() == 1) - RecPtr = JBPtrs[0]; - else { - // If there is more than one unwind in this function, make a PHI node to - // merge in all of the loaded values. - PHINode *PN = new PHINode(JBPtrs[0]->getType(), "jbptrs", RI); - for (unsigned i = 0, e = JBPtrs.size(); i != e; ++i) - PN->addIncoming(JBPtrs[i], JBPtrs[i]->getParent()); - RecPtr = PN; - } + if (Unwinds.empty() && Invokes.empty()) return false; + + NumInvokes += Invokes.size(); + NumUnwinds += Unwinds.size(); - // Now that we have a pointer to the whole record, remove the entry from the - // JBList. + // If we have an invoke instruction, insert a setjmp that dominates all + // invokes. After the setjmp, use a cond branch that goes to the original + // code path on zero, and to a designated 'catch' block of nonzero. + Value *OldJmpBufPtr = 0; + if (!Invokes.empty()) { + // First thing we need to do is scan the whole function for values that are + // live across unwind edges. Each value that is live across an unwind edge + // we spill into a stack location, guaranteeing that there is nothing live + // across the unwind edge. This process also splits all critical edges + // coming out of invoke's. + splitLiveRangesLiveAcrossInvokes(Invokes); + + BasicBlock *EntryBB = F.begin(); + + // Create an alloca for the incoming jump buffer ptr and the new jump buffer + // that needs to be restored on all exits from the function. This is an + // alloca because the value needs to be live across invokes. + AllocaInst *JmpBuf = + new AllocaInst(JBLinkTy, 0, "jblink", F.begin()->begin()); + std::vector Idx; Idx.push_back(Constant::getNullValue(Type::IntTy)); - Idx.push_back(ConstantUInt::get(Type::UIntTy, 0)); - Value *NextFieldPtr = new GetElementPtrInst(RecPtr, Idx, "NextField", RI); - Value *NextRec = new LoadInst(NextFieldPtr, "NextRecord", RI); - new StoreInst(NextRec, JBListHead, RI); - - // Now that we popped the top of the JBList, get a pointer to the jmpbuf and - // longjmp. - Idx[1] = ConstantUInt::get(Type::UIntTy, 1); - Idx[0] = new GetElementPtrInst(RecPtr, Idx, "JmpBuf", RI); - Idx[1] = ConstantInt::get(Type::IntTy, 1); - new CallInst(LongJmpFn, Idx, "", RI); - - // Now we set up the terminate block. - RI = TermBlock->getTerminator(); - - // Insert a new call to write(2, AbortMessage, AbortMessageLength); - writeAbortMessage(RI); - - // Insert a call to abort() - (new CallInst(AbortFn, std::vector(), "", RI))->setTailCall(); + Idx.push_back(ConstantUInt::get(Type::UIntTy, 1)); + OldJmpBufPtr = new GetElementPtrInst(JmpBuf, Idx, "OldBuf", + EntryBB->getTerminator()); + + // Copy the JBListHead to the alloca. + Value *OldBuf = new LoadInst(JBListHead, "oldjmpbufptr", true, + EntryBB->getTerminator()); + new StoreInst(OldBuf, OldJmpBufPtr, true, EntryBB->getTerminator()); + + // Add the new jumpbuf to the list. + new StoreInst(JmpBuf, JBListHead, true, EntryBB->getTerminator()); + + // Create the catch block. The catch block is basically a big switch + // statement that goes to all of the invoke catch blocks. + BasicBlock *CatchBB = new BasicBlock("setjmp.catch", &F); + + // Create an alloca which keeps track of which invoke is currently + // executing. For normal calls it contains zero. + AllocaInst *InvokeNum = new AllocaInst(Type::UIntTy, 0, "invokenum", + EntryBB->begin()); + new StoreInst(ConstantInt::get(Type::UIntTy, 0), InvokeNum, true, + EntryBB->getTerminator()); + + // Insert a load in the Catch block, and a switch on its value. By default, + // we go to a block that just does an unwind (which is the correct action + // for a standard call). + BasicBlock *UnwindBB = new BasicBlock("unwindbb", &F); + Unwinds.push_back(new UnwindInst(UnwindBB)); + + Value *CatchLoad = new LoadInst(InvokeNum, "invoke.num", true, CatchBB); + SwitchInst *CatchSwitch = + new SwitchInst(CatchLoad, UnwindBB, Invokes.size(), CatchBB); + + // Now that things are set up, insert the setjmp call itself. + + // Split the entry block to insert the conditional branch for the setjmp. + BasicBlock *ContBlock = EntryBB->splitBasicBlock(EntryBB->getTerminator(), + "setjmp.cont"); + + Idx[1] = ConstantUInt::get(Type::UIntTy, 0); + Value *JmpBufPtr = new GetElementPtrInst(JmpBuf, Idx, "TheJmpBuf", + EntryBB->getTerminator()); + Value *SJRet = new CallInst(SetJmpFn, JmpBufPtr, "sjret", + EntryBB->getTerminator()); + + // Compare the return value to zero. + Value *IsNormal = BinaryOperator::createSetEQ(SJRet, + Constant::getNullValue(SJRet->getType()), + "notunwind", EntryBB->getTerminator()); + // Nuke the uncond branch. + EntryBB->getTerminator()->eraseFromParent(); + + // Put in a new condbranch in its place. + new BranchInst(ContBlock, CatchBB, IsNormal, EntryBB); + + // At this point, we are all set up, rewrite each invoke instruction. + for (unsigned i = 0, e = Invokes.size(); i != e; ++i) + rewriteExpensiveInvoke(Invokes[i], i+1, InvokeNum, CatchSwitch); } - return Changed; + // We know that there is at least one unwind. + + // Create three new blocks, the block to load the jmpbuf ptr and compare + // against null, the block to do the longjmp, and the error block for if it + // is null. Add them at the end of the function because they are not hot. + BasicBlock *UnwindHandler = new BasicBlock("dounwind", &F); + BasicBlock *UnwindBlock = new BasicBlock("unwind", &F); + BasicBlock *TermBlock = new BasicBlock("unwinderror", &F); + + // If this function contains an invoke, restore the old jumpbuf ptr. + Value *BufPtr; + if (OldJmpBufPtr) { + // Before the return, insert a copy from the saved value to the new value. + BufPtr = new LoadInst(OldJmpBufPtr, "oldjmpbufptr", UnwindHandler); + new StoreInst(BufPtr, JBListHead, UnwindHandler); + } else { + BufPtr = new LoadInst(JBListHead, "ehlist", UnwindHandler); + } + + // Load the JBList, if it's null, then there was no catch! + Value *NotNull = BinaryOperator::createSetNE(BufPtr, + Constant::getNullValue(BufPtr->getType()), + "notnull", UnwindHandler); + new BranchInst(UnwindBlock, TermBlock, NotNull, UnwindHandler); + + // Create the block to do the longjmp. + // Get a pointer to the jmpbuf and longjmp. + std::vector Idx; + Idx.push_back(Constant::getNullValue(Type::IntTy)); + Idx.push_back(ConstantUInt::get(Type::UIntTy, 0)); + Idx[0] = new GetElementPtrInst(BufPtr, Idx, "JmpBuf", UnwindBlock); + Idx[1] = ConstantInt::get(Type::IntTy, 1); + new CallInst(LongJmpFn, Idx, "", UnwindBlock); + new UnreachableInst(UnwindBlock); + + // Set up the term block ("throw without a catch"). + new UnreachableInst(TermBlock); + + // Insert a new call to write(2, AbortMessage, AbortMessageLength); + writeAbortMessage(TermBlock->getTerminator()); + + // Insert a call to abort() + (new CallInst(AbortFn, std::vector(), "", + TermBlock->getTerminator()))->setTailCall(); + + + // Replace all unwinds with a branch to the unwind handler. + for (unsigned i = 0, e = Unwinds.size(); i != e; ++i) { + new BranchInst(UnwindHandler, Unwinds[i]); + Unwinds[i]->eraseFromParent(); + } + + // Finally, for any returns from this function, if this function contains an + // invoke, restore the old jmpbuf pointer to its input value. + if (OldJmpBufPtr) { + for (unsigned i = 0, e = Returns.size(); i != e; ++i) { + ReturnInst *R = Returns[i]; + + // Before the return, insert a copy from the saved value to the new value. + Value *OldBuf = new LoadInst(OldJmpBufPtr, "oldjmpbufptr", true, R); + new StoreInst(OldBuf, JBListHead, true, R); + } + } + + return true; } bool LowerInvoke::runOnFunction(Function &F) { From lattner at cs.uiuc.edu Tue Sep 27 16:33:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 16:33:23 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LowerInvoke.cpp Message-ID: <200509272133.QAA20078@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LowerInvoke.cpp updated: 1.29 -> 1.30 --- Log message: Avoid spilling stack slots... to stack slots. --- Diffs of the changes: (+6 -0) LowerInvoke.cpp | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/Transforms/Scalar/LowerInvoke.cpp diff -u llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.29 llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.30 --- llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.29 Tue Sep 27 16:18:17 2005 +++ llvm/lib/Transforms/Scalar/LowerInvoke.cpp Tue Sep 27 16:33:12 2005 @@ -334,6 +334,12 @@ cast(Inst->use_back())->getParent() == BB && !isa(Inst->use_back())) continue; + // If this is an alloca in the entry block, it's not a real register + // value. + if (AllocaInst *AI = dyn_cast(Inst)) + if (isa(AI->getArraySize()) && BB == F->begin()) + continue; + // Avoid iterator invalidation by copying users to a temporary vector. std::vector Users; for (Value::use_iterator UI = Inst->use_begin(), E = Inst->use_end(); From lattner at cs.uiuc.edu Tue Sep 27 17:13:47 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 17:13:47 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200509272213.RAA20540@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.23 -> 1.24 --- Log message: Add a new flag for targets where setjmp/longjmp saves/restores the signal mask, and _setjmp/_longjmp should be used instead (for llvm.setjmp/llvm.longjmp). --- Diffs of the changes: (+18 -1) TargetLowering.h | 19 ++++++++++++++++++- 1 files changed, 18 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.23 llvm/include/llvm/Target/TargetLowering.h:1.24 --- llvm/include/llvm/Target/TargetLowering.h:1.23 Sat Aug 27 14:09:02 2005 +++ llvm/include/llvm/Target/TargetLowering.h Tue Sep 27 17:13:36 2005 @@ -100,7 +100,7 @@ assert(RC && "This value type is not natively supported!"); return RC; } - + /// isTypeLegal - Return true if the target has native support for the /// specified value type. This means that it has a register that directly /// holds it without promotions or expansions. @@ -218,6 +218,12 @@ /// @brief Determine if the target supports unaligned memory accesses. bool allowsUnalignedMemoryAccesses() const { return allowUnalignedMemoryAccesses; } + + /// usesUnderscoreSetJmpLongJmp - Determine if we should use _setjmp or setjmp + /// to implement llvm.setjmp. + bool usesUnderscoreSetJmpLongJmp() const { + return UseUnderscoreSetJmpLongJmp; + } //===--------------------------------------------------------------------===// // TargetLowering Configuration Methods - These methods should be invoked by @@ -244,6 +250,13 @@ ShiftAmtHandling = OORSA; } + /// setUseUnderscoreSetJmpLongJmp - Indicate whether this target prefers to + /// use _setjmp and _longjmp to or implement llvm.setjmp/llvm.longjmp or + /// the non _ versions. Defaults to false. + void setUseUnderscoreSetJmpLongJmp(bool Val) { + UseUnderscoreSetJmpLongJmp = Val; + } + /// setSetCCIxExpensive - This is a short term hack for targets that codegen /// setcc as a conditional branch. This encourages the code generator to fold /// setcc operations into other operations if possible. @@ -379,6 +392,10 @@ /// SetCCResultContents - Information about the contents of the high-bits in /// the result of a setcc comparison operation. SetCCResultValue SetCCResultContents; + + /// UseUnderscoreSetJmpLongJmp - This target prefers to use _setjmp and + /// _longjmp to implement llvm.setjmp/llvm.longjmp. Defaults to false. + bool UseUnderscoreSetJmpLongJmp; /// RegClassForVT - This indicates the default register class to use for /// each ValueType the target supports natively. From lattner at cs.uiuc.edu Tue Sep 27 17:14:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 17:14:07 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200509272214.RAA20573@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.11 -> 1.12 --- Log message: initialize new flag --- Diffs of the changes: (+1 -0) TargetLowering.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.11 llvm/lib/Target/TargetLowering.cpp:1.12 --- llvm/lib/Target/TargetLowering.cpp:1.11 Sat Aug 27 14:09:02 2005 +++ llvm/lib/Target/TargetLowering.cpp Tue Sep 27 17:13:56 2005 @@ -29,6 +29,7 @@ memset(RegClassForVT, 0,MVT::LAST_VALUETYPE*sizeof(TargetRegisterClass*)); maxStoresPerMemSet = maxStoresPerMemCpy = maxStoresPerMemMove = 8; allowUnalignedMemoryAccesses = false; + UseUnderscoreSetJmpLongJmp = false; } TargetLowering::~TargetLowering() {} From lattner at cs.uiuc.edu Tue Sep 27 17:16:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 17:16:04 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200509272216.RAA20637@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.83 -> 1.84 --- Log message: If the target prefers it, use _setjmp/_longjmp should be used instead of setjmp/longjmp for llvm.setjmp/llvm.longjmp. --- Diffs of the changes: (+6 -2) SelectionDAGISel.cpp | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.83 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.84 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.83 Tue Sep 13 14:30:54 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Sep 27 17:15:53 2005 @@ -736,8 +736,12 @@ case Intrinsic::returnaddress: visitFrameReturnAddress(I, false); return; case Intrinsic::frameaddress: visitFrameReturnAddress(I, true); return; - case Intrinsic::setjmp: RenameFn = "setjmp"; break; - case Intrinsic::longjmp: RenameFn = "longjmp"; break; + case Intrinsic::setjmp: + RenameFn = "_setjmp"+!TLI.usesUnderscoreSetJmpLongJmp(); + break; + case Intrinsic::longjmp: + RenameFn = "_longjmp"+!TLI.usesUnderscoreSetJmpLongJmp(); + break; case Intrinsic::memcpy: visitMemIntrinsic(I, ISD::MEMCPY); return; case Intrinsic::memset: visitMemIntrinsic(I, ISD::MEMSET); return; case Intrinsic::memmove: visitMemIntrinsic(I, ISD::MEMMOVE); return; From lattner at cs.uiuc.edu Tue Sep 27 17:18:36 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 17:18:36 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Message-ID: <200509272218.RAA20698@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelLowering.cpp updated: 1.25 -> 1.26 --- Log message: Darwin, like many BSD systems, has a setjmp/longjmp which saves the signal mask on setjmp calls and restores it on longjmp calls (both of which require syscalls). This makes the calls REALLY slow. Use _setjmp/_longjmp instead. This speeds up hexxagon from 120.31s to 15.68s: from 5.53x slower than GCC to 28% faster than GCC. --- Diffs of the changes: (+3 -0) PPC32ISelLowering.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.25 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.26 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.25 Tue Sep 13 14:33:40 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Tue Sep 27 17:18:25 2005 @@ -28,6 +28,9 @@ // Fold away setcc operations if possible. setSetCCIsExpensive(); + // Use _setjmp/_longjmp instead of setjmp/longjmp. + setUseUnderscoreSetJmpLongJmp(true); + // Set up the register classes. addRegisterClass(MVT::i32, PPC32::GPRCRegisterClass); addRegisterClass(MVT::f32, PPC32::FPRCRegisterClass); From lattner at cs.uiuc.edu Tue Sep 27 17:27:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 17:27:30 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/GlobalOpt/2005-09-27-Crash.ll Message-ID: <200509272227.RAA20974@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/GlobalOpt: 2005-09-27-Crash.ll added (r1.1) --- Log message: Testcase for PR632: http://llvm.cs.uiuc.edu/PR632 --- Diffs of the changes: (+28 -0) 2005-09-27-Crash.ll | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+) Index: llvm/test/Regression/Transforms/GlobalOpt/2005-09-27-Crash.ll diff -c /dev/null llvm/test/Regression/Transforms/GlobalOpt/2005-09-27-Crash.ll:1.1 *** /dev/null Tue Sep 27 17:27:29 2005 --- llvm/test/Regression/Transforms/GlobalOpt/2005-09-27-Crash.ll Tue Sep 27 17:27:19 2005 *************** *** 0 **** --- 1,28 ---- + ; RUN: llvm-as < %s | opt -globalopt -disable-output + %RPyString = type { int, %arraytype.Char } + %arraytype.Char = type { int, [0 x sbyte] } + %arraytype.Signed = type { int, [0 x int] } + %functiontype.1 = type %RPyString* (int) + %structtype.test = type { int, %arraytype.Signed } + %structinstance.test = internal global { int, { int, [2 x int] } } { int 41, { int, [2 x int] } { int 2, [2 x int] [ int 100, int 101 ] } } ; <{ int, { int, [2 x int] } }*> [#uses=1] + + implementation ; Functions: + + fastcc void %pypy_array_constant() { + block0: + %tmp.9 = getelementptr %structtype.test* cast ({ int, { int, [2 x int] } }* %structinstance.test to %structtype.test*), int 0, uint 0 ; [#uses=0] + ret void + } + + fastcc void %new.varsizestruct.rpy_string() { + unreachable + } + + void %__entrypoint__pypy_array_constant() { + call fastcc void %pypy_array_constant( ) + ret void + } + + void %__entrypoint__raised_LLVMException() { + ret void + } From lattner at cs.uiuc.edu Tue Sep 27 17:28:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 17:28:23 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200509272228.RAA21068@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.57 -> 1.58 --- Log message: Fix a regression in my previous patch, fixing GlobalOpt/2005-09-27-Crash.ll and PR632: http://llvm.cs.uiuc.edu/PR632 . --- Diffs of the changes: (+1 -1) GlobalOpt.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.57 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.58 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.57 Tue Sep 27 00:02:43 2005 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Tue Sep 27 17:28:11 2005 @@ -337,7 +337,7 @@ Constant *SubInit = 0; ConstantExpr *CE = dyn_cast_or_null(ConstantFoldInstruction(GEP)); - if (CE && CE->getOpcode() == Instruction::GetElementPtr) + if (Init && CE && CE->getOpcode() == Instruction::GetElementPtr) SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE); Changed |= CleanupConstantGlobalUsers(GEP, SubInit); From lattner at cs.uiuc.edu Tue Sep 27 17:45:10 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 17:45:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LowerInvoke.cpp Message-ID: <200509272245.RAA21228@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LowerInvoke.cpp updated: 1.30 -> 1.31 --- Log message: add a note about a way to improve this code further, that I won't be getting to right now. --- Diffs of the changes: (+8 -0) LowerInvoke.cpp | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/lib/Transforms/Scalar/LowerInvoke.cpp diff -u llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.30 llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.31 --- llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.30 Tue Sep 27 16:33:12 2005 +++ llvm/lib/Transforms/Scalar/LowerInvoke.cpp Tue Sep 27 17:44:59 2005 @@ -412,6 +412,14 @@ NumInvokes += Invokes.size(); NumUnwinds += Unwinds.size(); + + // TODO: This is not an optimal way to do this. In particular, this always + // inserts setjmp calls into the entries of functions with invoke instructions + // even though there are possibly paths through the function that do not + // execute any invokes. In particular, for functions with early exits, e.g. + // the 'addMove' method in hexxagon, it would be nice to not have to do the + // setjmp stuff on the early exit path. This requires a bit of dataflow, but + // would not be too hard to do. // If we have an invoke instruction, insert a setjmp that dominates all // invokes. After the setjmp, use a cond branch that goes to the original From lattner at cs.uiuc.edu Tue Sep 27 17:51:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 17:51:32 -0500 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200509272251.RAA21316@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.170 -> 1.171 --- Log message: Turn on scheduling as llc-beta until Nate gets a chance to continue work on the dag combiner --- Diffs of the changes: (+1 -1) Makefile.programs | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.170 llvm-test/Makefile.programs:1.171 --- llvm-test/Makefile.programs:1.170 Thu Sep 15 20:28:37 2005 +++ llvm-test/Makefile.programs Tue Sep 27 17:51:20 2005 @@ -187,7 +187,7 @@ endif#DISABLE_DIFFS ifeq ($(ARCH),PowerPC) -LLCBETAOPTION := -enable-dag-combiner +LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),Alpha) LLCBETAOPTION := -enable-alpha-FTOI -enable-lsr-for-alpha From lattner at cs.uiuc.edu Tue Sep 27 20:34:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 27 Sep 2005 20:34:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Local.cpp Message-ID: <200509280134.UAA21922@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Local.cpp updated: 1.43 -> 1.44 --- Log message: Constant fold llvm.sqrt --- Diffs of the changes: (+9 -1) Local.cpp | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/Utils/Local.cpp diff -u llvm/lib/Transforms/Utils/Local.cpp:1.43 llvm/lib/Transforms/Utils/Local.cpp:1.44 --- llvm/lib/Transforms/Utils/Local.cpp:1.43 Mon Sep 26 00:27:10 2005 +++ llvm/lib/Transforms/Utils/Local.cpp Tue Sep 27 20:34:32 2005 @@ -240,7 +240,9 @@ const std::string &Name = F->getName(); switch (F->getIntrinsicID()) { - case Intrinsic::isunordered: return true; + case Intrinsic::isunordered: + case Intrinsic::sqrt: + return true; default: break; } @@ -321,6 +323,12 @@ return ConstantFP::get(Ty, log(V)); else if (Name == "log10" && V > 0) return ConstantFoldFP(log10, V, Ty); + else if (Name == "llvm.sqrt") { + if (V >= -0.0) + return ConstantFP::get(Ty, sqrt(V)); + else // Undefined + return ConstantFP::get(Ty, 0.0); + } break; case 's': if (Name == "sin") From lattner at cs.uiuc.edu Wed Sep 28 02:17:13 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 02:17:13 -0500 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c Message-ID: <200509280717.CAA23720@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.116 -> 1.117 --- Log message: Fix a bug I introduced that could cause generation of invalid LLVM code for code like "false || foo()" --- Diffs of the changes: (+9 -1) llvm-expand.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletion(-) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.116 llvm-gcc/gcc/llvm-expand.c:1.117 --- llvm-gcc/gcc/llvm-expand.c:1.116 Sat Sep 24 16:41:53 2005 +++ llvm-gcc/gcc/llvm-expand.c Wed Sep 28 02:16:59 2005 @@ -1814,7 +1814,7 @@ llvm_emit_label(Fn, getLabelDeclBlock(Label)); } -/* Generate RTL for the start of a loop. EXIT_FLAG is nonzero if this +/* Generate LLVM for the start of a loop. EXIT_FLAG is nonzero if this loop should be exited by `break_something'. This is a loop for which `expand_continue' will jump to the top of the loop. @@ -3402,6 +3402,14 @@ /* Add a PHI node to merge together the two computed values */ + if (CondBr->NumOperands == 1 && CondBr->Operands[0] != DoneBlock) { + /* The cond branch terminating FromBlock was folded to not go to the done + * block at all. This code is only reachable from the TestBlock. + */ + return cast_if_type_not_equal(Fn, SecondOp, + llvm_type_get_from_tree(TREE_TYPE(exp))); + } + PHI = llvm_instruction_new(BoolTy, "shortcirc_val", O_PHINode, 4); PHI->Operands[0] = isAndExpr ? llvm_constant_bool_false : llvm_constant_bool_true; From lattner at cs.uiuc.edu Wed Sep 28 11:58:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 11:58:17 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200509281658.LAA24981@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.44 -> 1.45 --- Log message: Select Constant nodes to TargetConstant nodes --- Diffs of the changes: (+19 -5) DAGISelEmitter.cpp | 24 +++++++++++++++++++----- 1 files changed, 19 insertions(+), 5 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.44 llvm/utils/TableGen/DAGISelEmitter.cpp:1.45 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.44 Mon Sep 26 17:10:24 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed Sep 28 11:58:06 2005 @@ -1088,14 +1088,28 @@ if (Val[0] == 'T' && Val[1] == 'm' && Val[2] == 'p') { // Already selected this operand, just return the tmpval. return atoi(Val.c_str()+3); + } + + unsigned ResNo = Ctr++; + if (!N->isLeaf() && N->getOperator()->getName() == "imm") { + switch (N->getType()) { + default: assert(0 && "Unknown type for constant node!"); + case MVT::i1: OS << " bool Tmp"; break; + case MVT::i8: OS << " unsigned char Tmp"; break; + case MVT::i16: OS << " unsigned short Tmp"; break; + case MVT::i32: OS << " unsigned Tmp"; break; + case MVT::i64: OS << " uint64_t Tmp"; break; + } + OS << ResNo << "C = cast(" << Val << ")->getValue();\n"; + OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetConstant(Tmp" + << ResNo << "C, MVT::" << getEnumName(N->getType()) << ");\n"; } else { - unsigned ResNo = Ctr++; OS << " SDOperand Tmp" << ResNo << " = Select(" << Val << ");\n"; - // Add Tmp to VariableMap, so that we don't multiply select this - // value if used multiple times by this pattern result. - Val = "Tmp"+utostr(ResNo); - return ResNo; } + // Add Tmp to VariableMap, so that we don't multiply select this + // value if used multiple times by this pattern result. + Val = "Tmp"+utostr(ResNo); + return ResNo; } if (N->isLeaf()) { From lattner at cs.uiuc.edu Wed Sep 28 12:07:20 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 12:07:20 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509281707.MAA25089@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.78 -> 1.79 --- Log message: These nodes are all autogenerated --- Diffs of the changes: (+0 -44) PPC32ISelDAGToDAG.cpp | 44 -------------------------------------------- 1 files changed, 44 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.78 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.79 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.78 Tue Sep 27 12:45:33 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Wed Sep 28 12:07:09 2005 @@ -678,25 +678,6 @@ } return SDOperand(N, 0); } - case ISD::Constant: { - assert(N->getValueType(0) == MVT::i32); - unsigned v = (unsigned)cast(N)->getValue(); - - // NOTE: This doesn't use SelectNodeTo, because doing that will prevent - // folding shared immediates into other the second instruction that - // uses it. - if (isInt16(v)) - return CurDAG->getTargetNode(PPC::LI, MVT::i32, getI32Imm(v)); - - unsigned Hi = Hi16(v); - unsigned Lo = Lo16(v); - - if (!Lo) - return CurDAG->getTargetNode(PPC::LIS, MVT::i32, getI32Imm(Hi)); - - SDOperand Top = CurDAG->getTargetNode(PPC::LIS, MVT::i32, getI32Imm(Hi)); - return CurDAG->getTargetNode(PPC::ORI, MVT::i32, Top, getI32Imm(Lo)); - } case ISD::UNDEF: if (N->getValueType(0) == MVT::i32) CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_GPR, MVT::i32); @@ -768,21 +749,6 @@ CurDAG->ReplaceAllUsesWith(N, Result.Val); return SDOperand(Result.Val, Op.ResNo); } - case ISD::SIGN_EXTEND_INREG: - switch(cast(N->getOperand(1))->getVT()) { - default: assert(0 && "Illegal type in SIGN_EXTEND_INREG"); break; - case MVT::i16: - CurDAG->SelectNodeTo(N, PPC::EXTSH, MVT::i32, Select(N->getOperand(0))); - break; - case MVT::i8: - CurDAG->SelectNodeTo(N, PPC::EXTSB, MVT::i32, Select(N->getOperand(0))); - break; - } - return SDOperand(N, 0); - case ISD::CTLZ: - assert(N->getValueType(0) == MVT::i32); - CurDAG->SelectNodeTo(N, PPC::CNTLZW, MVT::i32, Select(N->getOperand(0))); - return SDOperand(N, 0); case PPCISD::FSEL: CurDAG->SelectNodeTo(N, PPC::FSEL, N->getValueType(0), Select(N->getOperand(0)), @@ -960,16 +926,6 @@ Select(N->getOperand(1))); return SDOperand(N, 0); } - case ISD::MULHS: - assert(N->getValueType(0) == MVT::i32); - CurDAG->SelectNodeTo(N, PPC::MULHW, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); - case ISD::MULHU: - assert(N->getValueType(0) == MVT::i32); - CurDAG->SelectNodeTo(N, PPC::MULHWU, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); case ISD::AND: { unsigned Imm; // If this is an and of a value rotated between 0 and 31 bits and then and'd From lattner at cs.uiuc.edu Wed Sep 28 12:13:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 12:13:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509281713.MAA25269@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.103 -> 1.104 --- Log message: learn to codegen not as NOR instead of xoris/xori --- Diffs of the changes: (+5 -1) PowerPCInstrInfo.td | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.103 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.104 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.103 Mon Sep 26 17:20:16 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Wed Sep 28 12:13:15 2005 @@ -765,7 +765,11 @@ // Arbitrary immediate support. Implement in terms of LIS/ORI. def : Pat<(i32 imm:$imm), (ORI (LIS (HI16 imm:$imm)), (LO16 imm:$imm))>; - + +// Implement the 'not' operation with the NOR instruction. +def NOT : Pat<(not GPRC:$in), + (NOR GPRC:$in, GPRC:$in)>; + // or by an arbitrary immediate. def : Pat<(or GPRC:$in, imm:$imm), (ORIS (ORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>; From lattner at cs.uiuc.edu Wed Sep 28 12:55:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 12:55:21 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/nor.ll Message-ID: <200509281755.MAA25615@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: nor.ll added (r1.1) --- Log message: simple tests for nor generation --- Diffs of the changes: (+12 -0) nor.ll | 12 ++++++++++++ 1 files changed, 12 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/nor.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/nor.ll:1.1 *** /dev/null Wed Sep 28 12:55:20 2005 --- llvm/test/Regression/CodeGen/PowerPC/nor.ll Wed Sep 28 12:55:10 2005 *************** *** 0 **** --- 1,12 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 | grep nor | wc -l | grep 2 + + int %test1(int %X) { + %Y = xor int %X, -1 + ret int %Y + } + + int %test2(int %X, int %Y) { + %Z = or int %X, %Y + %R = xor int %Z, -1 + ret int %R + } From lattner at cs.uiuc.edu Wed Sep 28 12:58:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 12:58:07 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200509281758.MAA25681@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.45 -> 1.46 --- Log message: Prefer cheaper patterns to more expensive ones. Print the costs to the generated file --- Diffs of the changes: (+50 -39) DAGISelEmitter.cpp | 89 +++++++++++++++++++++++++++++------------------------ 1 files changed, 50 insertions(+), 39 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.45 llvm/utils/TableGen/DAGISelEmitter.cpp:1.46 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.45 Wed Sep 28 11:58:06 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed Sep 28 12:57:56 2005 @@ -995,6 +995,52 @@ }); } +/// getPatternSize - Return the 'size' of this pattern. We want to match large +/// patterns before small ones. This is used to determine the size of a +/// pattern. +static unsigned getPatternSize(TreePatternNode *P) { + assert(MVT::isInteger(P->getType()) || MVT::isFloatingPoint(P->getType()) && + "Not a valid pattern node to size!"); + unsigned Size = 1; // The node itself. + + // Count children in the count if they are also nodes. + for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) { + TreePatternNode *Child = P->getChild(i); + if (!Child->isLeaf() && Child->getType() != MVT::Other) + Size += getPatternSize(Child); + } + + return Size; +} + +/// getResultPatternCost - Compute the number of instructions for this pattern. +/// This is a temporary hack. We should really include the instruction +/// latencies in this calculation. +static unsigned getResultPatternCost(TreePatternNode *P) { + if (P->isLeaf()) return 0; + + unsigned Cost = P->getOperator()->isSubClassOf("Instruction"); + for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) + Cost += getResultPatternCost(P->getChild(i)); + return Cost; +} + +// PatternSortingPredicate - return true if we prefer to match LHS before RHS. +// In particular, we want to match maximal patterns first and lowest cost within +// a particular complexity first. +struct PatternSortingPredicate { + bool operator()(DAGISelEmitter::PatternToMatch *LHS, + DAGISelEmitter::PatternToMatch *RHS) { + unsigned LHSSize = getPatternSize(LHS->first); + unsigned RHSSize = getPatternSize(RHS->first); + if (LHSSize > RHSSize) return true; // LHS -> bigger -> less cost + if (LHSSize < RHSSize) return false; + + // If the patterns have equal complexity, compare generated instruction cost + return getResultPatternCost(LHS->second) second); + } +}; + /// EmitMatchForPattern - Emit a matcher for N, going to the label for PatternNo /// if the match fails. At this point, we already know that the opcode for N /// matches, and the SDNode for the result has the RootName specified name. @@ -1160,16 +1206,16 @@ unsigned PatternNo = PatternCount++; OS << " { // Pattern #" << PatternNo << ": "; Pattern.first->print(OS); + OS << "\n // Emits: "; + Pattern.second->print(OS); OS << "\n"; + OS << " // Pattern complexity = " << getPatternSize(Pattern.first) + << " cost = " << getResultPatternCost(Pattern.second) << "\n"; // Emit the matcher, capturing named arguments in VariableMap. std::map VariableMap; EmitMatchForPattern(Pattern.first, "N", VariableMap, PatternNo, OS); - OS << " // Emit: "; - Pattern.second->print(OS); - OS << "\n"; - unsigned TmpNo = 0; unsigned Res = CodeGenPatternResult(Pattern.second, TmpNo, VariableMap, OS); @@ -1179,41 +1225,6 @@ OS << " }\n P" << PatternNo << "Fail:\n"; } -/// getPatternSize - Return the 'size' of this pattern. We want to match large -/// patterns before small ones. This is used to determine the size of a -/// pattern. -static unsigned getPatternSize(TreePatternNode *P) { - assert(MVT::isInteger(P->getType()) || MVT::isFloatingPoint(P->getType()) && - "Not a valid pattern node to size!"); - unsigned Size = 1; // The node itself. - - // Count children in the count if they are also nodes. - for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) { - TreePatternNode *Child = P->getChild(i); - if (!Child->isLeaf() && Child->getType() != MVT::Other) - Size += getPatternSize(Child); - } - - return Size; -} - -// PatternSortingPredicate - return true if we prefer to match LHS before RHS. -// In particular, we want to match maximal patterns first and lowest cost within -// a particular complexity first. -struct PatternSortingPredicate { - bool operator()(DAGISelEmitter::PatternToMatch *LHS, - DAGISelEmitter::PatternToMatch *RHS) { - unsigned LHSSize = getPatternSize(LHS->first); - unsigned RHSSize = getPatternSize(RHS->first); - if (LHSSize > RHSSize) return true; // LHS -> bigger -> less cost - if (LHSSize < RHSSize) return false; - - // If they are equal, compare cost. - // FIXME: Compute cost! - return false; - } -}; - namespace { /// CompareByRecordName - An ordering predicate that implements less-than by From lattner at cs.uiuc.edu Wed Sep 28 13:04:33 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 13:04:33 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/eqv-andc-orc-nor.ll eqv.ll nor.ll Message-ID: <200509281804.NAA25847@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: eqv-andc-orc-nor.ll added (r1.1) eqv.ll (r1.2) removed nor.ll (r1.1) removed --- Log message: Consolidate the eqv.ll and nor.ll files together. Add a missed eqv case. --- Diffs of the changes: (+58 -0) eqv-andc-orc-nor.ll | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 58 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/eqv-andc-orc-nor.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/eqv-andc-orc-nor.ll:1.1 *** /dev/null Wed Sep 28 13:04:32 2005 --- llvm/test/Regression/CodeGen/PowerPC/eqv-andc-orc-nor.ll Wed Sep 28 13:04:22 2005 *************** *** 0 **** --- 1,58 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 | grep eqv | wc -l | grep 3 && + ; RUN: llvm-as < %s | llc -march=ppc32 | grep andc | wc -l | grep 2 && + ; RUN: llvm-as < %s | llc -march=ppc32 | grep orc | wc -l | grep 2 && + ; RUN: llvm-as < %s | llc -march=ppc32 | grep nor | wc -l | grep 2 + + int %EQV1(int %X, int %Y) { + %A = xor int %X, %Y + %B = xor int %A, -1 + ret int %B + } + + int %EQV2(int %X, int %Y) { + %A = xor int %X, -1 + %B = xor int %A, %Y + ret int %B + } + + int %EQV3(int %X, int %Y) { + %A = xor int %X, -1 + %B = xor int %Y, %A + ret int %B + } + + int %ANDC1(int %X, int %Y) { + %A = xor int %Y, -1 + %B = and int %X, %A + ret int %B + } + + int %ANDC2(int %X, int %Y) { + %A = xor int %X, -1 + %B = and int %A, %Y + ret int %B + } + + int %ORC1(int %X, int %Y) { + %A = xor int %Y, -1 + %B = or int %X, %A + ret int %B + } + + int %ORC2(int %X, int %Y) { + %A = xor int %X, -1 + %B = or int %A, %Y + ret int %B + } + + int %NOR1(int %X) { + %Y = xor int %X, -1 + ret int %Y + } + + int %NOR2(int %X, int %Y) { + %Z = or int %X, %Y + %R = xor int %Z, -1 + ret int %R + } + From lattner at cs.uiuc.edu Wed Sep 28 13:05:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 13:05:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509281805.NAA25886@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.79 -> 1.80 --- Log message: Implement PowerPC/eqv-andc-orc-nor.ll:EQV3 --- Diffs of the changes: (+5 -1) PPC32ISelDAGToDAG.cpp | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.79 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.80 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.79 Wed Sep 28 12:07:09 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Wed Sep 28 13:04:52 2005 @@ -1012,12 +1012,16 @@ N = I; return SDOperand(N, 0); } - // Finally, check for the case where we are being asked to select + // Check for the case where we are being asked to select // xor (not(a), b) which is equivalent to not(xor a, b), which is eqv if (isOprNot(N->getOperand(0).Val)) CurDAG->SelectNodeTo(N, PPC::EQV, MVT::i32, Select(N->getOperand(0).getOperand(0)), Select(N->getOperand(1))); + else if (isOprNot(N->getOperand(1).Val)) + CurDAG->SelectNodeTo(N, PPC::EQV, MVT::i32, + Select(N->getOperand(1).getOperand(0)), + Select(N->getOperand(0))); else CurDAG->SelectNodeTo(N, PPC::XOR, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); From lattner at cs.uiuc.edu Wed Sep 28 13:09:10 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 13:09:10 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/eqv-andc-orc-nor.ll Message-ID: <200509281809.NAA25968@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: eqv-andc-orc-nor.ll updated: 1.1 -> 1.2 --- Log message: add testcase for nand --- Diffs of the changes: (+7 -1) eqv-andc-orc-nor.ll | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletion(-) Index: llvm/test/Regression/CodeGen/PowerPC/eqv-andc-orc-nor.ll diff -u llvm/test/Regression/CodeGen/PowerPC/eqv-andc-orc-nor.ll:1.1 llvm/test/Regression/CodeGen/PowerPC/eqv-andc-orc-nor.ll:1.2 --- llvm/test/Regression/CodeGen/PowerPC/eqv-andc-orc-nor.ll:1.1 Wed Sep 28 13:04:22 2005 +++ llvm/test/Regression/CodeGen/PowerPC/eqv-andc-orc-nor.ll Wed Sep 28 13:08:58 2005 @@ -1,7 +1,8 @@ ; RUN: llvm-as < %s | llc -march=ppc32 | grep eqv | wc -l | grep 3 && ; RUN: llvm-as < %s | llc -march=ppc32 | grep andc | wc -l | grep 2 && ; RUN: llvm-as < %s | llc -march=ppc32 | grep orc | wc -l | grep 2 && -; RUN: llvm-as < %s | llc -march=ppc32 | grep nor | wc -l | grep 2 +; RUN: llvm-as < %s | llc -march=ppc32 | grep nor | wc -l | grep 2 && +; RUN: llvm-as < %s | llc -march=ppc32 | grep nand | wc -l | grep 1 int %EQV1(int %X, int %Y) { %A = xor int %X, %Y @@ -56,3 +57,8 @@ ret int %R } +int %NAND1(int %X, int %Y) { + %Z = and int %X, %Y + %W = xor int %Z, -1 + ret int %W +} From lattner at cs.uiuc.edu Wed Sep 28 13:11:02 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 13:11:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509281811.NAA26038@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.104 -> 1.105 --- Log message: add support for missed eqv tests --- Diffs of the changes: (+9 -0) PowerPCInstrInfo.td | 9 +++++++++ 1 files changed, 9 insertions(+) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.104 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.105 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.104 Wed Sep 28 12:13:15 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Wed Sep 28 13:10:51 2005 @@ -766,10 +766,18 @@ def : Pat<(i32 imm:$imm), (ORI (LIS (HI16 imm:$imm)), (LO16 imm:$imm))>; + // Implement the 'not' operation with the NOR instruction. def NOT : Pat<(not GPRC:$in), (NOR GPRC:$in, GPRC:$in)>; +// EQV patterns +def EQV1 : Pat<(xor (not GPRC:$in1), GPRC:$in2), + (EQV GPRC:$in1, GPRC:$in2)>; +// FIXME: This should be autogenerated from the above due to xor commutativity. +def EQV2 : Pat<(xor GPRC:$in1, (not GPRC:$in2)), + (EQV GPRC:$in1, GPRC:$in2)>; + // or by an arbitrary immediate. def : Pat<(or GPRC:$in, imm:$imm), (ORIS (ORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>; @@ -778,6 +786,7 @@ (XORIS (XORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>; + // Same as above, but using a temporary. FIXME: implement temporaries :) /* def : Pattern<(xor GPRC:$in, imm:$imm), From lattner at cs.uiuc.edu Wed Sep 28 13:12:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 13:12:48 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509281812.NAA26077@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.80 -> 1.81 --- Log message: All (xor *) cases are autogenerated now --- Diffs of the changes: (+0 -43) PPC32ISelDAGToDAG.cpp | 43 ------------------------------------------- 1 files changed, 43 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.80 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.81 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.80 Wed Sep 28 13:04:52 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Wed Sep 28 13:12:37 2005 @@ -983,49 +983,6 @@ CurDAG->SelectNodeTo(N, PPC::OR, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); return SDOperand(N, 0); - case ISD::XOR: - // Check whether or not this node is a logical 'not'. This is represented - // by llvm as a xor with the constant value -1 (all bits set). If this is a - // 'not', then fold 'or' into 'nor', and so forth for the supported ops. - if (isOprNot(N)) { - unsigned Opc; - SDOperand Val = Select(N->getOperand(0)); - switch (Val.isTargetOpcode() ? Val.getTargetOpcode() : 0) { - default: Opc = 0; break; - case PPC::OR: Opc = PPC::NOR; break; - case PPC::AND: Opc = PPC::NAND; break; - case PPC::XOR: Opc = PPC::EQV; break; - } - if (Opc) - CurDAG->SelectNodeTo(N, Opc, MVT::i32, Val.getOperand(0), - Val.getOperand(1)); - else - CurDAG->SelectNodeTo(N, PPC::NOR, MVT::i32, Val, Val); - return SDOperand(N, 0); - } - // If this is a xor with an immediate other than -1, then codegen it as high - // and low 16 bit immediate xors. - if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), - N->getOperand(1), - PPC::XORIS, PPC::XORI)) { - CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); - N = I; - return SDOperand(N, 0); - } - // Check for the case where we are being asked to select - // xor (not(a), b) which is equivalent to not(xor a, b), which is eqv - if (isOprNot(N->getOperand(0).Val)) - CurDAG->SelectNodeTo(N, PPC::EQV, MVT::i32, - Select(N->getOperand(0).getOperand(0)), - Select(N->getOperand(1))); - else if (isOprNot(N->getOperand(1).Val)) - CurDAG->SelectNodeTo(N, PPC::EQV, MVT::i32, - Select(N->getOperand(1).getOperand(0)), - Select(N->getOperand(0))); - else - CurDAG->SelectNodeTo(N, PPC::XOR, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); case ISD::SHL: { unsigned Imm, SH, MB, ME; if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) && From lattner at cs.uiuc.edu Wed Sep 28 13:28:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 13:28:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509281828.NAA26179@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.105 -> 1.106 --- Log message: expose commutativity information --- Diffs of the changes: (+17 -8) PowerPCInstrInfo.td | 25 +++++++++++++++++-------- 1 files changed, 17 insertions(+), 8 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.105 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.106 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.105 Wed Sep 28 13:10:51 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Wed Sep 28 13:27:58 2005 @@ -81,27 +81,36 @@ SDTCisVTSmallerThanOp<2, 1> ]>; +//===----------------------------------------------------------------------===// +// Selection DAG Node Properties. +// +// Note: These are hard coded into tblgen. +// +class SDNodeProperty; +def SDNPCommutative : SDNodeProperty; //===----------------------------------------------------------------------===// // Selection DAG Node definitions. // -class SDNode { +class SDNode props = [], string sdclass = "SDNode"> { string Opcode = opcode; string SDClass = sdclass; + list Properties = props; SDTypeProfile TypeProfile = typeprof; } def set; def node; -def imm : SDNode<"ISD::Constant" , SDTImm , "ConstantSDNode">; -def vt : SDNode<"ISD::VALUETYPE" , SDTVT , "VTSDNode">; -def and : SDNode<"ISD::AND" , SDTIntBinOp>; -def or : SDNode<"ISD::OR" , SDTIntBinOp>; -def xor : SDNode<"ISD::XOR" , SDTIntBinOp>; -def add : SDNode<"ISD::ADD" , SDTBinOp>; +def imm : SDNode<"ISD::Constant" , SDTImm , [], "ConstantSDNode">; +def vt : SDNode<"ISD::VALUETYPE" , SDTVT , [], "VTSDNode">; +def and : SDNode<"ISD::AND" , SDTIntBinOp, [SDNPCommutative]>; +def or : SDNode<"ISD::OR" , SDTIntBinOp, [SDNPCommutative]>; +def xor : SDNode<"ISD::XOR" , SDTIntBinOp, [SDNPCommutative]>; +def add : SDNode<"ISD::ADD" , SDTBinOp , [SDNPCommutative]>; def sub : SDNode<"ISD::SUB" , SDTBinOp>; -def mul : SDNode<"ISD::MUL" , SDTBinOp>; +def mul : SDNode<"ISD::MUL" , SDTBinOp , [SDNPCommutative]>; def sdiv : SDNode<"ISD::SDIV" , SDTBinOp>; def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp>; From lattner at cs.uiuc.edu Wed Sep 28 13:28:40 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 13:28:40 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200509281828.NAA26239@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.46 -> 1.47 DAGISelEmitter.h updated: 1.25 -> 1.26 --- Log message: collect commutativity information --- Diffs of the changes: (+24 -0) DAGISelEmitter.cpp | 16 ++++++++++++++++ DAGISelEmitter.h | 8 ++++++++ 2 files changed, 24 insertions(+) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.46 llvm/utils/TableGen/DAGISelEmitter.cpp:1.47 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.46 Wed Sep 28 12:57:56 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed Sep 28 13:28:29 2005 @@ -137,6 +137,22 @@ NumResults = TypeProfile->getValueAsInt("NumResults"); NumOperands = TypeProfile->getValueAsInt("NumOperands"); + // Parse the properties. + Properties = 0; + ListInit *LI = R->getValueAsListInit("Properties"); + for (unsigned i = 0, e = LI->getSize(); i != e; ++i) { + DefInit *DI = dynamic_cast(LI->getElement(i)); + assert(DI && "Properties list must be list of defs!"); + if (DI->getDef()->getName() == "SDNPCommutative") { + Properties |= 1 << SDNPCommutative; + } else { + std::cerr << "Unknown SD Node property '" << DI->getDef()->getName() + << "' on node '" << R->getName() << "'!\n"; + exit(1); + } + } + + // Parse the type constraints. ListInit *Constraints = TypeProfile->getValueAsListInit("Constraints"); for (unsigned i = 0, e = Constraints->getSize(); i != e; ++i) { Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.25 llvm/utils/TableGen/DAGISelEmitter.h:1.26 --- llvm/utils/TableGen/DAGISelEmitter.h:1.25 Fri Sep 23 19:40:24 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Wed Sep 28 13:28:29 2005 @@ -69,6 +69,7 @@ Record *Def; std::string EnumName; std::string SDClassName; + unsigned Properties; unsigned NumResults; int NumOperands; std::vector TypeConstraints; @@ -84,6 +85,13 @@ const std::vector &getTypeConstraints() const { return TypeConstraints; } + + // SelectionDAG node properties. + enum SDNP { SDNPCommutative }; + + /// hasProperty - Return true if this node has the specified property. + /// + bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); } /// ApplyTypeConstraints - Given a node in a pattern, apply the type /// constraints for this node to the operands of the node. This returns From lattner at cs.uiuc.edu Wed Sep 28 14:01:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 14:01:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509281901.OAA26463@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.106 -> 1.107 --- Log message: Nate pointed out that mulh[us] are commutative as well. Thanks! --- Diffs of the changes: (+2 -2) PowerPCInstrInfo.td | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.106 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.107 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.106 Wed Sep 28 13:27:58 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Wed Sep 28 14:01:44 2005 @@ -113,8 +113,8 @@ def mul : SDNode<"ISD::MUL" , SDTBinOp , [SDNPCommutative]>; def sdiv : SDNode<"ISD::SDIV" , SDTBinOp>; def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; -def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp>; -def mulhu : SDNode<"ISD::MULHU" , SDTIntBinOp>; +def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp, [SDNPCommutative]>; +def mulhu : SDNode<"ISD::MULHU" , SDTIntBinOp, [SDNPCommutative]>; def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; From lattner at cs.uiuc.edu Wed Sep 28 14:27:37 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 14:27:37 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200509281927.OAA27070@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.47 -> 1.48 DAGISelEmitter.h updated: 1.26 -> 1.27 --- Log message: Emit an error if instructions or patterns are defined but can never match. Currently we check that immediate values live on the RHS of commutative operators. Defining ORI like this, for example: def ORI : DForm_4<24, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), "ori $dst, $src1, $src2", [(set GPRC:$dst, (or immZExt16:$src2, GPRC:$src1))]>; results in: tblgen: In ORI: Instruction can never match: Immediate values must be on the RHS of commutative operators! --- Diffs of the changes: (+52 -3) DAGISelEmitter.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- DAGISelEmitter.h | 5 +++++ 2 files changed, 52 insertions(+), 3 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.47 llvm/utils/TableGen/DAGISelEmitter.cpp:1.48 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.47 Wed Sep 28 13:28:29 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed Sep 28 14:27:25 2005 @@ -372,6 +372,34 @@ } } +/// canPatternMatch - If it is impossible for this pattern to match on this +/// target, fill in Reason and return false. Otherwise, return true. This is +/// used as a santity check for .td files (to prevent people from writing stuff +/// that can never possibly work), and to prevent the pattern permuter from +/// generating stuff that is useless. +bool TreePatternNode::canPatternMatch(std::string &Reason, DAGISelEmitter &ISE) { + if (isLeaf()) return true; + + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) + if (!getChild(i)->canPatternMatch(Reason, ISE)) + return false; + + // If this node is a commutative operator, check that the LHS isn't an + // immediate. + const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(getOperator()); + if (NodeInfo.hasProperty(SDNodeInfo::SDNPCommutative)) { + // Scan all of the operands of the node and make sure that only the last one + // is a constant node. + for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i) + if (!getChild(i)->isLeaf() && + getChild(i)->getOperator()->getName() == "imm") { + Reason = "Immediate value must be on the RHS of commutative operators!"; + return false; + } + } + + return true; +} //===----------------------------------------------------------------------===// // TreePattern implementation @@ -962,6 +990,11 @@ continue; // Not a set of a single value (not handled so far) TreePatternNode *SrcPattern = Pattern->getChild(1)->clone(); + + std::string Reason; + if (!SrcPattern->canPatternMatch(Reason, *this)) + I->error("Instruction can never match: " + Reason); + TreePatternNode *DstPattern = II->second.getResultPattern(); PatternsToMatch.push_back(std::make_pair(SrcPattern, DstPattern)); } @@ -999,6 +1032,11 @@ if (Result->getNumTrees() != 1) Result->error("Cannot handle instructions producing instructions " "with temporaries yet!"); + + std::string Reason; + if (!Pattern->getOnlyTree()->canPatternMatch(Reason, *this)) + Pattern->error("Pattern can never match: " + Reason); + PatternsToMatch.push_back(std::make_pair(Pattern->getOnlyTree(), Result->getOnlyTree())); } @@ -1011,6 +1049,12 @@ }); } +// GenerateVariants - Generate variants. For example, commutative patterns can +// match multiple ways. Add them to PatternsToMatch as well. +void DAGISelEmitter::GenerateVariants() { + +} + /// getPatternSize - Return the 'size' of this pattern. We want to match large /// patterns before small ones. This is used to determine the size of a /// pattern. @@ -1331,13 +1375,13 @@ ParseInstructions(); ParsePatterns(); - // FIXME: Generate variants. For example, commutative patterns can match + // Generate variants. For example, commutative patterns can match // multiple ways. Add them to PatternsToMatch as well. + GenerateVariants(); // At this point, we have full information about the 'Patterns' we need to // parse, both implicitly from instructions as well as from explicit pattern - // definitions. - + // definitions. Emit the resultant instruction selector. EmitInstructionSelector(OS); for (std::map::iterator I = PatternFragments.begin(), Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.26 llvm/utils/TableGen/DAGISelEmitter.h:1.27 --- llvm/utils/TableGen/DAGISelEmitter.h:1.26 Wed Sep 28 13:28:29 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Wed Sep 28 14:27:25 2005 @@ -204,6 +204,10 @@ if (getChild(i)->ContainsUnresolvedType()) return true; return false; } + + /// canPatternMatch - Return false if it is impossible for this pattern to + /// match on this target. + bool canPatternMatch(std::string &Reason, DAGISelEmitter &ISE); }; @@ -369,6 +373,7 @@ void ParsePatternFragments(std::ostream &OS); void ParseInstructions(); void ParsePatterns(); + void GenerateVariants(); void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, std::map &InstInputs, From lattner at cs.uiuc.edu Wed Sep 28 15:58:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 15:58:17 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200509282058.PAA28171@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.48 -> 1.49 DAGISelEmitter.h updated: 1.27 -> 1.28 --- Log message: add support for an associative marker --- Diffs of the changes: (+7 -5) DAGISelEmitter.cpp | 6 ++++-- DAGISelEmitter.h | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.48 llvm/utils/TableGen/DAGISelEmitter.cpp:1.49 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.48 Wed Sep 28 14:27:25 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed Sep 28 15:58:06 2005 @@ -145,6 +145,8 @@ assert(DI && "Properties list must be list of defs!"); if (DI->getDef()->getName() == "SDNPCommutative") { Properties |= 1 << SDNPCommutative; + } else if (DI->getDef()->getName() == "SDNPAssociative") { + Properties |= 1 << SDNPAssociative; } else { std::cerr << "Unknown SD Node property '" << DI->getDef()->getName() << "' on node '" << R->getName() << "'!\n"; @@ -377,7 +379,7 @@ /// used as a santity check for .td files (to prevent people from writing stuff /// that can never possibly work), and to prevent the pattern permuter from /// generating stuff that is useless. -bool TreePatternNode::canPatternMatch(std::string &Reason, DAGISelEmitter &ISE) { +bool TreePatternNode::canPatternMatch(std::string &Reason, DAGISelEmitter &ISE){ if (isLeaf()) return true; for (unsigned i = 0, e = getNumChildren(); i != e; ++i) @@ -1052,9 +1054,9 @@ // GenerateVariants - Generate variants. For example, commutative patterns can // match multiple ways. Add them to PatternsToMatch as well. void DAGISelEmitter::GenerateVariants() { - } + /// getPatternSize - Return the 'size' of this pattern. We want to match large /// patterns before small ones. This is used to determine the size of a /// pattern. Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.27 llvm/utils/TableGen/DAGISelEmitter.h:1.28 --- llvm/utils/TableGen/DAGISelEmitter.h:1.27 Wed Sep 28 14:27:25 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Wed Sep 28 15:58:06 2005 @@ -87,7 +87,7 @@ } // SelectionDAG node properties. - enum SDNP { SDNPCommutative }; + enum SDNP { SDNPCommutative, SDNPAssociative }; /// hasProperty - Return true if this node has the specified property. /// @@ -205,8 +205,8 @@ return false; } - /// canPatternMatch - Return false if it is impossible for this pattern to - /// match on this target. + /// canPatternMatch - If it is impossible for this pattern to match on this + /// target, fill in Reason and return false. Otherwise, return true. bool canPatternMatch(std::string &Reason, DAGISelEmitter &ISE); }; From lattner at cs.uiuc.edu Wed Sep 28 15:58:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 15:58:50 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509282058.PAA28204@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.107 -> 1.108 --- Log message: Mark associative nodes as associative --- Diffs of the changes: (+12 -6) PowerPCInstrInfo.td | 18 ++++++++++++------ 1 files changed, 12 insertions(+), 6 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.107 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.108 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.107 Wed Sep 28 14:01:44 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Wed Sep 28 15:58:39 2005 @@ -87,7 +87,8 @@ // Note: These are hard coded into tblgen. // class SDNodeProperty; -def SDNPCommutative : SDNodeProperty; +def SDNPCommutative : SDNodeProperty; // X op Y == Y op X +def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z) //===----------------------------------------------------------------------===// // Selection DAG Node definitions. @@ -105,12 +106,17 @@ def imm : SDNode<"ISD::Constant" , SDTImm , [], "ConstantSDNode">; def vt : SDNode<"ISD::VALUETYPE" , SDTVT , [], "VTSDNode">; -def and : SDNode<"ISD::AND" , SDTIntBinOp, [SDNPCommutative]>; -def or : SDNode<"ISD::OR" , SDTIntBinOp, [SDNPCommutative]>; -def xor : SDNode<"ISD::XOR" , SDTIntBinOp, [SDNPCommutative]>; -def add : SDNode<"ISD::ADD" , SDTBinOp , [SDNPCommutative]>; +def and : SDNode<"ISD::AND" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; +def or : SDNode<"ISD::OR" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; +def xor : SDNode<"ISD::XOR" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; +def add : SDNode<"ISD::ADD" , SDTBinOp , + [SDNPCommutative, SDNPAssociative]>; def sub : SDNode<"ISD::SUB" , SDTBinOp>; -def mul : SDNode<"ISD::MUL" , SDTBinOp , [SDNPCommutative]>; +def mul : SDNode<"ISD::MUL" , SDTBinOp , + [SDNPCommutative, SDNPAssociative]>; def sdiv : SDNode<"ISD::SDIV" , SDTBinOp>; def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp, [SDNPCommutative]>; From lattner at cs.uiuc.edu Wed Sep 28 17:27:02 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 17:27:02 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200509282227.RAA29037@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.67 -> 1.68 --- Log message: Add FP versions of the binary operators, keeping the int and fp worlds seperate. --- Diffs of the changes: (+4 -1) SelectionDAGNodes.h | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.67 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.68 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.67 Thu Sep 1 19:14:40 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Wed Sep 28 17:26:50 2005 @@ -105,8 +105,11 @@ BUILD_PAIR, - // Simple binary arithmetic operators. + // Simple integer binary arithmetic operators. ADD, SUB, MUL, SDIV, UDIV, SREM, UREM, + + // Simple binary floating point operators. + FADD, FSUB, FMUL, FDIV, FREM, // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing // an unsigned/signed value of type i[2*n], then return the top part. From lattner at cs.uiuc.edu Wed Sep 28 17:28:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 17:28:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp Message-ID: <200509282228.RAA29100@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.13 -> 1.14 LegalizeDAG.cpp updated: 1.186 -> 1.187 SelectionDAG.cpp updated: 1.193 -> 1.194 SelectionDAGISel.cpp updated: 1.84 -> 1.85 --- Log message: Add FP versions of the binary operators, keeping the int and fp worlds seperate. Though I have done extensive testing, it is possible that this will break things in configs I can't test. Please let me know if this causes a problem and I'll fix it ASAP. --- Diffs of the changes: (+209 -87) DAGCombiner.cpp | 143 ++++++++++++++++++++++++++++++++++----------------- LegalizeDAG.cpp | 45 ++++++++++++---- SelectionDAG.cpp | 61 ++++++++++++++------- SelectionDAGISel.cpp | 47 ++++++++++++---- 4 files changed, 209 insertions(+), 87 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.13 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.14 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.13 Mon Sep 19 17:34:01 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Sep 28 17:28:18 2005 @@ -115,6 +115,12 @@ SDOperand visitZERO_EXTEND(SDNode *N); SDOperand visitSIGN_EXTEND_INREG(SDNode *N); SDOperand visitTRUNCATE(SDNode *N); + + SDOperand visitFADD(SDNode *N); + SDOperand visitFSUB(SDNode *N); + SDOperand visitFMUL(SDNode *N); + SDOperand visitFDIV(SDNode *N); + SDOperand visitFREM(SDNode *N); SDOperand visitSINT_TO_FP(SDNode *N); SDOperand visitUINT_TO_FP(SDNode *N); SDOperand visitFP_TO_SINT(SDNode *N); @@ -341,6 +347,11 @@ case ISD::ZERO_EXTEND: return visitZERO_EXTEND(N); case ISD::SIGN_EXTEND_INREG: return visitSIGN_EXTEND_INREG(N); case ISD::TRUNCATE: return visitTRUNCATE(N); + case ISD::FADD: return visitFADD(N); + case ISD::FSUB: return visitFSUB(N); + case ISD::FMUL: return visitFMUL(N); + case ISD::FDIV: return visitFDIV(N); + case ISD::FREM: return visitFREM(N); case ISD::SINT_TO_FP: return visitSINT_TO_FP(N); case ISD::UINT_TO_FP: return visitUINT_TO_FP(N); case ISD::FP_TO_SINT: return visitFP_TO_SINT(N); @@ -375,8 +386,6 @@ SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); - ConstantFPSDNode *N0CFP = dyn_cast(N0); - ConstantFPSDNode *N1CFP = dyn_cast(N1); MVT::ValueType VT = N0.getValueType(); // fold (add c1, c2) -> c1+c2 @@ -390,9 +399,6 @@ // fold (add x, 0) -> x if (N1C && N1C->isNullValue()) return N0; - // fold floating point (add c1, c2) -> c1+c2 - if (N0CFP && N1CFP) - return DAG.getConstantFP(N0CFP->getValue() + N1CFP->getValue(), VT); // fold (add (add x, c1), c2) -> (add x, c1+c2) if (N1C && N0.getOpcode() == ISD::ADD) { ConstantSDNode *N00C = dyn_cast(N0.getOperand(0)); @@ -404,12 +410,6 @@ return DAG.getNode(ISD::ADD, VT, N0.getOperand(0), DAG.getConstant(N1C->getValue()+N01C->getValue(), VT)); } - // fold (A + (-B)) -> A-B - if (N1.getOpcode() == ISD::FNEG) - return DAG.getNode(ISD::SUB, VT, N0, N1.getOperand(0)); - // fold ((-A) + B) -> B-A - if (N0.getOpcode() == ISD::FNEG) - return DAG.getNode(ISD::SUB, VT, N1, N0.getOperand(0)); // fold ((0-A) + B) -> B-A if (N0.getOpcode() == ISD::SUB && isa(N0.getOperand(0)) && cast(N0.getOperand(0))->isNullValue()) @@ -418,9 +418,8 @@ if (N1.getOpcode() == ISD::SUB && isa(N1.getOperand(0)) && cast(N1.getOperand(0))->isNullValue()) return DAG.getNode(ISD::SUB, VT, N0, N1.getOperand(1)); - // fold (A+(B-A)) -> B for non-fp types - if (N1.getOpcode() == ISD::SUB && N0 == N1.getOperand(1) && - !MVT::isFloatingPoint(N1.getValueType())) + // fold (A+(B-A)) -> B + if (N1.getOpcode() == ISD::SUB && N0 == N1.getOperand(1)) return N1.getOperand(0); return SDOperand(); } @@ -430,8 +429,6 @@ SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0.Val); ConstantSDNode *N1C = dyn_cast(N1.Val); - ConstantFPSDNode *N0CFP = dyn_cast(N0.Val); - ConstantFPSDNode *N1CFP = dyn_cast(N1.Val); // fold (sub c1, c2) -> c1-c2 if (N0C && N1C) @@ -440,21 +437,12 @@ // fold (sub x, 0) -> x if (N1C && N1C->isNullValue()) return N0; - // fold floating point (sub c1, c2) -> c1-c2 - if (N0CFP && N1CFP) - return DAG.getConstantFP(N0CFP->getValue() - N1CFP->getValue(), - N->getValueType(0)); // fold (A+B)-A -> B - if (N0.getOpcode() == ISD::ADD && N0.getOperand(0) == N1 && - !MVT::isFloatingPoint(N1.getValueType())) + if (N0.getOpcode() == ISD::ADD && N0.getOperand(0) == N1) return N0.getOperand(1); // fold (A+B)-B -> A - if (N0.getOpcode() == ISD::ADD && N0.getOperand(1) == N1 && - !MVT::isFloatingPoint(N1.getValueType())) + if (N0.getOpcode() == ISD::ADD && N0.getOperand(1) == N1) return N0.getOperand(0); - // fold (A-(-B)) -> A+B - if (N1.getOpcode() == ISD::FNEG) - return DAG.getNode(ISD::ADD, N0.getValueType(), N0, N1.getOperand(0)); return SDOperand(); } @@ -463,8 +451,6 @@ SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); - ConstantFPSDNode *N0CFP = dyn_cast(N0); - ConstantFPSDNode *N1CFP = dyn_cast(N1); MVT::ValueType VT = N0.getValueType(); // fold (mul c1, c2) -> c1*c2 @@ -499,10 +485,6 @@ return DAG.getNode(ISD::MUL, VT, N0.getOperand(0), DAG.getConstant(N1C->getValue()*N01C->getValue(), VT)); } - // fold floating point (mul c1, c2) -> c1*c2 - if (N0CFP && N1CFP) - return DAG.getConstantFP(N0CFP->getValue() * N1CFP->getValue(), - N->getValueType(0)); return SDOperand(); } @@ -511,17 +493,11 @@ SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0.Val); ConstantSDNode *N1C = dyn_cast(N1.Val); - ConstantFPSDNode *N0CFP = dyn_cast(N0.Val); - ConstantFPSDNode *N1CFP = dyn_cast(N1.Val); // fold (sdiv c1, c2) -> c1/c2 if (N0C && N1C && !N1C->isNullValue()) return DAG.getConstant(N0C->getSignExtended() / N1C->getSignExtended(), N->getValueType(0)); - // fold floating point (sdiv c1, c2) -> c1/c2 - if (N0CFP && N1CFP) - return DAG.getConstantFP(N0CFP->getValue() / N1CFP->getValue(), - N->getValueType(0)); return SDOperand(); } @@ -548,17 +524,11 @@ SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); - ConstantFPSDNode *N0CFP = dyn_cast(N0); - ConstantFPSDNode *N1CFP = dyn_cast(N1); // fold (srem c1, c2) -> c1%c2 if (N0C && N1C && !N1C->isNullValue()) return DAG.getConstant(N0C->getSignExtended() % N1C->getSignExtended(), N->getValueType(0)); - // fold floating point (srem c1, c2) -> fmod(c1, c2) - if (N0CFP && N1CFP) - return DAG.getConstantFP(fmod(N0CFP->getValue(),N1CFP->getValue()), - N->getValueType(0)); return SDOperand(); } @@ -1233,6 +1203,89 @@ return SDOperand(); } +SDOperand DAGCombiner::visitFADD(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + MVT::ValueType VT = N->getValueType(0); + + if (ConstantFPSDNode *N0CFP = dyn_cast(N0)) + if (ConstantFPSDNode *N1CFP = dyn_cast(N1)) { + // fold floating point (fadd c1, c2) + return DAG.getConstantFP(N0CFP->getValue() + N1CFP->getValue(), + N->getValueType(0)); + } + // fold (A + (-B)) -> A-B + if (N1.getOpcode() == ISD::FNEG) + return DAG.getNode(ISD::FSUB, VT, N0, N1.getOperand(0)); + + // fold ((-A) + B) -> B-A + if (N0.getOpcode() == ISD::FNEG) + return DAG.getNode(ISD::FSUB, VT, N1, N0.getOperand(0)); + + return SDOperand(); +} + +SDOperand DAGCombiner::visitFSUB(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + MVT::ValueType VT = N->getValueType(0); + + if (ConstantFPSDNode *N0CFP = dyn_cast(N0)) + if (ConstantFPSDNode *N1CFP = dyn_cast(N1)) { + // fold floating point (fsub c1, c2) + return DAG.getConstantFP(N0CFP->getValue() - N1CFP->getValue(), + N->getValueType(0)); + } + // fold (A-(-B)) -> A+B + if (N1.getOpcode() == ISD::FNEG) + return DAG.getNode(ISD::FADD, N0.getValueType(), N0, N1.getOperand(0)); + + return SDOperand(); +} + +SDOperand DAGCombiner::visitFMUL(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + MVT::ValueType VT = N->getValueType(0); + + if (ConstantFPSDNode *N0CFP = dyn_cast(N0)) + if (ConstantFPSDNode *N1CFP = dyn_cast(N1)) { + // fold floating point (fmul c1, c2) + return DAG.getConstantFP(N0CFP->getValue() * N1CFP->getValue(), + N->getValueType(0)); + } + return SDOperand(); +} + +SDOperand DAGCombiner::visitFDIV(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + MVT::ValueType VT = N->getValueType(0); + + if (ConstantFPSDNode *N0CFP = dyn_cast(N0)) + if (ConstantFPSDNode *N1CFP = dyn_cast(N1)) { + // fold floating point (fdiv c1, c2) + return DAG.getConstantFP(N0CFP->getValue() / N1CFP->getValue(), + N->getValueType(0)); + } + return SDOperand(); +} + +SDOperand DAGCombiner::visitFREM(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + MVT::ValueType VT = N->getValueType(0); + + if (ConstantFPSDNode *N0CFP = dyn_cast(N0)) + if (ConstantFPSDNode *N1CFP = dyn_cast(N1)) { + // fold floating point (frem c1, c2) -> fmod(c1, c2) + return DAG.getConstantFP(fmod(N0CFP->getValue(),N1CFP->getValue()), + N->getValueType(0)); + } + return SDOperand(); +} + + SDOperand DAGCombiner::visitSINT_TO_FP(SDNode *N) { SDOperand N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast(N0); Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.186 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.187 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.186 Fri Sep 9 19:20:18 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Sep 28 17:28:18 2005 @@ -209,7 +209,7 @@ : BitsToDouble(0x4330000000000000ULL), MVT::f64); // subtract the bias - SDOperand Sub = DAG.getNode(ISD::SUB, MVT::f64, Load, Bias); + SDOperand Sub = DAG.getNode(ISD::FSUB, MVT::f64, Load, Bias); // final result SDOperand Result; // handle final rounding @@ -1531,6 +1531,10 @@ case ISD::SHL: case ISD::SRL: case ISD::SRA: + case ISD::FADD: + case ISD::FSUB: + case ISD::FMUL: + case ISD::FDIV: Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS switch (getTypeAction(Node->getOperand(1).getValueType())) { case Expand: assert(0 && "Not possible"); @@ -1548,6 +1552,7 @@ case ISD::UREM: case ISD::SREM: + case ISD::FREM: Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { @@ -1715,7 +1720,7 @@ case ISD::FNEG: { // Expand Y = FNEG(X) -> Y = SUB -0.0, X Tmp2 = DAG.getConstantFP(-0.0, Node->getValueType(0)); - Result = LegalizeOp(DAG.getNode(ISD::SUB, Node->getValueType(0), + Result = LegalizeOp(DAG.getNode(ISD::FSUB, Node->getValueType(0), Tmp2, Tmp1)); break; } @@ -1840,7 +1845,7 @@ Node->getOperand(0), Tmp2, ISD::SETLT); True = DAG.getNode(ISD::FP_TO_SINT, NVT, Node->getOperand(0)); False = DAG.getNode(ISD::FP_TO_SINT, NVT, - DAG.getNode(ISD::SUB, VT, Node->getOperand(0), + DAG.getNode(ISD::FSUB, VT, Node->getOperand(0), Tmp2)); False = DAG.getNode(ISD::XOR, NVT, False, DAG.getConstant(1ULL << ShiftAmt, NVT)); @@ -2193,19 +2198,29 @@ case ISD::SUB: case ISD::MUL: // The input may have strange things in the top bits of the registers, but - // these operations don't care. They may have wierd bits going out, but + // these operations don't care. They may have weird bits going out, but // that too is okay if they are integer operations. Tmp1 = PromoteOp(Node->getOperand(0)); Tmp2 = PromoteOp(Node->getOperand(1)); assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT); Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2); - - // However, if this is a floating point operation, they will give excess - // precision that we may not be able to tolerate. If we DO allow excess - // precision, just leave it, otherwise excise it. + break; + case ISD::FADD: + case ISD::FSUB: + case ISD::FMUL: + // The input may have strange things in the top bits of the registers, but + // these operations don't care. + Tmp1 = PromoteOp(Node->getOperand(0)); + Tmp2 = PromoteOp(Node->getOperand(1)); + assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT); + Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2); + + // Floating point operations will give excess precision that we may not be + // able to tolerate. If we DO allow excess precision, just leave it, + // otherwise excise it. // FIXME: Why would we need to round FP ops more than integer ones? // Is Round(Add(Add(A,B),C)) != Round(Add(Round(Add(A,B)), C)) - if (MVT::isFloatingPoint(NVT) && NoExcessFPPrecision) + if (NoExcessFPPrecision) Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, DAG.getValueType(VT)); break; @@ -2228,6 +2243,18 @@ Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, DAG.getValueType(VT)); break; + case ISD::FDIV: + case ISD::FREM: + // These operators require that their input be fp extended. + Tmp1 = PromoteOp(Node->getOperand(0)); + Tmp2 = PromoteOp(Node->getOperand(1)); + Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2); + + // Perform FP_ROUND: this is probably overly pessimistic. + if (NoExcessFPPrecision) + Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, + DAG.getValueType(VT)); + break; case ISD::UDIV: case ISD::UREM: Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.193 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.194 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.193 Thu Sep 22 19:55:52 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Sep 28 17:28:18 2005 @@ -36,6 +36,8 @@ switch (Opcode) { case ISD::ADD: case ISD::MUL: + case ISD::FADD: + case ISD::FMUL: case ISD::AND: case ISD::OR: case ISD::XOR: return true; @@ -869,8 +871,7 @@ return getSetCC(VT, N1, N2, NewCond); } - if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) && - MVT::isInteger(N1.getValueType())) { + if (Cond == ISD::SETEQ || Cond == ISD::SETNE) { if (N1.getOpcode() == ISD::ADD || N1.getOpcode() == ISD::SUB || N1.getOpcode() == ISD::XOR) { // Simplify (X+Y) == (X+Z) --> Y == Z @@ -1187,8 +1188,8 @@ } break; case ISD::FNEG: - if (OpOpcode == ISD::SUB) // -(X-Y) -> (Y-X) - return getNode(ISD::SUB, VT, Operand.Val->getOperand(1), + if (OpOpcode == ISD::FSUB) // -(X-Y) -> (Y-X) + return getNode(ISD::FSUB, VT, Operand.Val->getOperand(1), Operand.Val->getOperand(0)); if (OpOpcode == ISD::FNEG) // --X -> X return Operand.Val->getOperand(0); @@ -1236,6 +1237,13 @@ case ISD::MUL: case ISD::SDIV: case ISD::SREM: + assert(MVT::isInteger(N1.getValueType()) && "Should use F* for FP ops"); + // fall through. + case ISD::FADD: + case ISD::FSUB: + case ISD::FMUL: + case ISD::FDIV: + case ISD::FREM: assert(N1.getValueType() == N2.getValueType() && N1.getValueType() == VT && "Binary operator types must match!"); break; @@ -1513,13 +1521,13 @@ if (N2CFP) { double C1 = N1CFP->getValue(), C2 = N2CFP->getValue(); switch (Opcode) { - case ISD::ADD: return getConstantFP(C1 + C2, VT); - case ISD::SUB: return getConstantFP(C1 - C2, VT); - case ISD::MUL: return getConstantFP(C1 * C2, VT); - case ISD::SDIV: + case ISD::FADD: return getConstantFP(C1 + C2, VT); + case ISD::FSUB: return getConstantFP(C1 - C2, VT); + case ISD::FMUL: return getConstantFP(C1 * C2, VT); + case ISD::FDIV: if (C2) return getConstantFP(C1 / C2, VT); break; - case ISD::SREM : + case ISD::FREM : if (C2) return getConstantFP(fmod(C1, C2), VT); break; default: break; @@ -1623,33 +1631,39 @@ break; case ISD::ADD: if (!CombinerEnabled) { - if (N2.getOpcode() == ISD::FNEG) // (A+ (-B) -> A-B - return getNode(ISD::SUB, VT, N1, N2.getOperand(0)); - if (N1.getOpcode() == ISD::FNEG) // ((-A)+B) -> B-A - return getNode(ISD::SUB, VT, N2, N1.getOperand(0)); if (N1.getOpcode() == ISD::SUB && isa(N1.getOperand(0)) && cast(N1.getOperand(0))->getValue() == 0) return getNode(ISD::SUB, VT, N2, N1.getOperand(1)); // (0-A)+B -> B-A if (N2.getOpcode() == ISD::SUB && isa(N2.getOperand(0)) && cast(N2.getOperand(0))->getValue() == 0) return getNode(ISD::SUB, VT, N1, N2.getOperand(1)); // A+(0-B) -> A-B - if (N2.getOpcode() == ISD::SUB && N1 == N2.Val->getOperand(1) && - !MVT::isFloatingPoint(N2.getValueType())) + if (N2.getOpcode() == ISD::SUB && N1 == N2.Val->getOperand(1)) return N2.Val->getOperand(0); // A+(B-A) -> B } break; + case ISD::FADD: + if (!CombinerEnabled) { + if (N2.getOpcode() == ISD::FNEG) // (A+ (-B) -> A-B + return getNode(ISD::FSUB, VT, N1, N2.getOperand(0)); + if (N1.getOpcode() == ISD::FNEG) // ((-A)+B) -> B-A + return getNode(ISD::FSUB, VT, N2, N1.getOperand(0)); + } + break; + case ISD::SUB: if (!CombinerEnabled) { if (N1.getOpcode() == ISD::ADD) { - if (N1.Val->getOperand(0) == N2 && - !MVT::isFloatingPoint(N2.getValueType())) + if (N1.Val->getOperand(0) == N2) return N1.Val->getOperand(1); // (A+B)-A == B - if (N1.Val->getOperand(1) == N2 && - !MVT::isFloatingPoint(N2.getValueType())) + if (N1.Val->getOperand(1) == N2) return N1.Val->getOperand(0); // (A+B)-B == A } + } + break; + case ISD::FSUB: + if (!CombinerEnabled) { if (N2.getOpcode() == ISD::FNEG) // (A- (-B) -> A+B - return getNode(ISD::ADD, VT, N1, N2.getOperand(0)); + return getNode(ISD::FADD, VT, N1, N2.getOperand(0)); } break; case ISD::FP_ROUND_INREG: @@ -2333,7 +2347,12 @@ case ISD::SHL: return "shl"; case ISD::SRA: return "sra"; case ISD::SRL: return "srl"; - + case ISD::FADD: return "fadd"; + case ISD::FSUB: return "fsub"; + case ISD::FMUL: return "fmul"; + case ISD::FDIV: return "fdiv"; + case ISD::FREM: return "frem"; + case ISD::SETCC: return "setcc"; case ISD::SELECT: return "select"; case ISD::SELECT_CC: return "select_cc"; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.84 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.85 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.84 Tue Sep 27 17:15:53 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Sep 28 17:28:18 2005 @@ -353,14 +353,34 @@ // void visitBinary(User &I, unsigned Opcode, bool isShift = false); - void visitAdd(User &I) { visitBinary(I, ISD::ADD); } + void visitAdd(User &I) { + visitBinary(I, I.getType()->isFloatingPoint() ? ISD::FADD : ISD::ADD); + } void visitSub(User &I); - void visitMul(User &I) { visitBinary(I, ISD::MUL); } + void visitMul(User &I) { + visitBinary(I, I.getType()->isFloatingPoint() ? ISD::FMUL : ISD::MUL); + } void visitDiv(User &I) { - visitBinary(I, I.getType()->isUnsigned() ? ISD::UDIV : ISD::SDIV); + unsigned Opc; + const Type *Ty = I.getType(); + if (Ty->isFloatingPoint()) + Opc = ISD::FDIV; + else if (Ty->isUnsigned()) + Opc = ISD::UDIV; + else + Opc = ISD::SDIV; + visitBinary(I, Opc); } void visitRem(User &I) { - visitBinary(I, I.getType()->isUnsigned() ? ISD::UREM : ISD::SREM); + unsigned Opc; + const Type *Ty = I.getType(); + if (Ty->isFloatingPoint()) + Opc = ISD::FREM; + else if (Ty->isUnsigned()) + Opc = ISD::UREM; + else + Opc = ISD::SREM; + visitBinary(I, Opc); } void visitAnd(User &I) { visitBinary(I, ISD::AND); } void visitOr (User &I) { visitBinary(I, ISD::OR); } @@ -491,14 +511,17 @@ void SelectionDAGLowering::visitSub(User &I) { // -0.0 - X --> fneg - if (ConstantFP *CFP = dyn_cast(I.getOperand(0))) - if (CFP->isExactlyValue(-0.0)) { - SDOperand Op2 = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2)); - return; - } - - visitBinary(I, ISD::SUB); + if (I.getType()->isFloatingPoint()) { + if (ConstantFP *CFP = dyn_cast(I.getOperand(0))) + if (CFP->isExactlyValue(-0.0)) { + SDOperand Op2 = getValue(I.getOperand(1)); + setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2)); + return; + } + visitBinary(I, ISD::FSUB); + } else { + visitBinary(I, ISD::SUB); + } } void SelectionDAGLowering::visitBinary(User &I, unsigned Opcode, bool isShift) { From lattner at cs.uiuc.edu Wed Sep 28 17:29:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 17:29:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelPattern.cpp Message-ID: <200509282229.RAA29168@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelPattern.cpp updated: 1.64 -> 1.65 --- Log message: Add FP versions of the binary operators, keeping the int and fp worlds seperate. Though I have done extensive testing, it is possible that this will break things in configs I can't test. Please let me know if this causes a problem and I'll fix it ASAP. --- Diffs of the changes: (+65 -58) IA64ISelPattern.cpp | 123 +++++++++++++++++++++++++++------------------------- 1 files changed, 65 insertions(+), 58 deletions(-) Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.64 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.65 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.64 Thu Sep 1 19:15:30 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Wed Sep 28 17:29:17 2005 @@ -72,8 +72,8 @@ setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand); setOperationAction(ISD::SEXTLOAD , MVT::i32 , Expand); - setOperationAction(ISD::SREM , MVT::f32 , Expand); - setOperationAction(ISD::SREM , MVT::f64 , Expand); + setOperationAction(ISD::FREM , MVT::f32 , Expand); + setOperationAction(ISD::FREM , MVT::f64 , Expand); setOperationAction(ISD::UREM , MVT::f32 , Expand); setOperationAction(ISD::UREM , MVT::f64 , Expand); @@ -1240,20 +1240,28 @@ BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(Tmp2); return Result; } - - case ISD::ADD: { - if(DestType == MVT::f64 && N.getOperand(0).getOpcode() == ISD::MUL && - N.getOperand(0).Val->hasOneUse()) { // if we can fold this add - // into an fma, do so: - // ++FusedFP; // Statistic + + case ISD::FADD: { + if (N.getOperand(0).getOpcode() == ISD::FMUL && + N.getOperand(0).Val->hasOneUse()) { // if we can fold this add + // into an fma, do so: + // ++FusedFP; // Statistic Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); Tmp3 = SelectExpr(N.getOperand(1)); BuildMI(BB, IA64::FMA, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; // early exit } + + //else, fallthrough: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, IA64::FADD, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + } - if(DestType != MVT::f64 && N.getOperand(0).getOpcode() == ISD::SHL && + case ISD::ADD: { + if (N.getOperand(0).getOpcode() == ISD::SHL && N.getOperand(0).Val->hasOneUse()) { // if we might be able to fold // this add into a shladd, try: ConstantSDNode *CSD = NULL; @@ -1273,75 +1281,71 @@ //else, fallthrough: Tmp1 = SelectExpr(N.getOperand(0)); - if(DestType != MVT::f64) { // integer addition: - switch (ponderIntegerAdditionWith(N.getOperand(1), Tmp3)) { - case 1: // adding a constant that's 14 bits - BuildMI(BB, IA64::ADDIMM14, 2, Result).addReg(Tmp1).addSImm(Tmp3); - return Result; // early exit - } // fallthrough and emit a reg+reg ADD: - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, IA64::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2); - } else { // this is a floating point addition - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, IA64::FADD, 2, Result).addReg(Tmp1).addReg(Tmp2); - } + switch (ponderIntegerAdditionWith(N.getOperand(1), Tmp3)) { + case 1: // adding a constant that's 14 bits + BuildMI(BB, IA64::ADDIMM14, 2, Result).addReg(Tmp1).addSImm(Tmp3); + return Result; // early exit + } // fallthrough and emit a reg+reg ADD: + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, IA64::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; } + case ISD::FMUL: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, IA64::FMPY, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::MUL: { - if(DestType != MVT::f64) { // TODO: speed! + // TODO: speed! /* FIXME if(N.getOperand(1).getOpcode() != ISD::Constant) { // if not a const mul */ - // boring old integer multiply with xma - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - - unsigned TempFR1=MakeReg(MVT::f64); - unsigned TempFR2=MakeReg(MVT::f64); - unsigned TempFR3=MakeReg(MVT::f64); - BuildMI(BB, IA64::SETFSIG, 1, TempFR1).addReg(Tmp1); - BuildMI(BB, IA64::SETFSIG, 1, TempFR2).addReg(Tmp2); - BuildMI(BB, IA64::XMAL, 1, TempFR3).addReg(TempFR1).addReg(TempFR2) - .addReg(IA64::F0); - BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(TempFR3); - return Result; // early exit - /* FIXME } else { // we are multiplying by an integer constant! yay - return Reg = SelectExpr(BuildConstmulSequence(N)); // avert your eyes! - } */ - } - else { // floating point multiply + // boring old integer multiply with xma Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, IA64::FMPY, 2, Result).addReg(Tmp1).addReg(Tmp2); - return Result; - } + + unsigned TempFR1=MakeReg(MVT::f64); + unsigned TempFR2=MakeReg(MVT::f64); + unsigned TempFR3=MakeReg(MVT::f64); + BuildMI(BB, IA64::SETFSIG, 1, TempFR1).addReg(Tmp1); + BuildMI(BB, IA64::SETFSIG, 1, TempFR2).addReg(Tmp2); + BuildMI(BB, IA64::XMAL, 1, TempFR3).addReg(TempFR1).addReg(TempFR2) + .addReg(IA64::F0); + BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(TempFR3); + return Result; // early exit + /* FIXME } else { // we are multiplying by an integer constant! yay + return Reg = SelectExpr(BuildConstmulSequence(N)); // avert your eyes! + } */ } - case ISD::SUB: { - if(DestType == MVT::f64 && N.getOperand(0).getOpcode() == ISD::MUL && + case ISD::FSUB: + if(N.getOperand(0).getOpcode() == ISD::FMUL && N.getOperand(0).Val->hasOneUse()) { // if we can fold this sub // into an fms, do so: - // ++FusedFP; // Statistic + // ++FusedFP; // Statistic Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); Tmp3 = SelectExpr(N.getOperand(1)); BuildMI(BB, IA64::FMS, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; // early exit } + Tmp2 = SelectExpr(N.getOperand(1)); - if(DestType != MVT::f64) { // integer subtraction: - switch (ponderIntegerSubtractionFrom(N.getOperand(0), Tmp3)) { - case 1: // subtracting *from* an 8 bit constant: - BuildMI(BB, IA64::SUBIMM8, 2, Result).addSImm(Tmp3).addReg(Tmp2); - return Result; // early exit - } // fallthrough and emit a reg+reg SUB: - Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, IA64::SUB, 2, Result).addReg(Tmp1).addReg(Tmp2); - } else { // this is a floating point subtraction - Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, IA64::FSUB, 2, Result).addReg(Tmp1).addReg(Tmp2); - } + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, IA64::FSUB, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + + case ISD::SUB: { + Tmp2 = SelectExpr(N.getOperand(1)); + switch (ponderIntegerSubtractionFrom(N.getOperand(0), Tmp3)) { + case 1: // subtracting *from* an 8 bit constant: + BuildMI(BB, IA64::SUBIMM8, 2, Result).addSImm(Tmp3).addReg(Tmp2); + return Result; // early exit + } // fallthrough and emit a reg+reg SUB: + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, IA64::SUB, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; } @@ -1584,6 +1588,7 @@ return Result; } + case ISD::FDIV: case ISD::SDIV: case ISD::UDIV: case ISD::SREM: @@ -1601,8 +1606,10 @@ bool isSigned=false; switch(N.getOpcode()) { + case ISD::FDIV: case ISD::SDIV: isModulus=false; isSigned=true; break; case ISD::UDIV: isModulus=false; isSigned=false; break; + case ISD::FREM: case ISD::SREM: isModulus=true; isSigned=true; break; case ISD::UREM: isModulus=true; isSigned=false; break; } From lattner at cs.uiuc.edu Wed Sep 28 17:29:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 17:29:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200509282229.RAA29178@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.179 -> 1.180 --- Log message: Add FP versions of the binary operators, keeping the int and fp worlds seperate. Though I have done extensive testing, it is possible that this will break things in configs I can't test. Please let me know if this causes a problem and I'll fix it ASAP. --- Diffs of the changes: (+21 -6) X86ISelPattern.cpp | 27 +++++++++++++++++++++------ 1 files changed, 21 insertions(+), 6 deletions(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.179 llvm/lib/Target/X86/X86ISelPattern.cpp:1.180 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.179 Wed Sep 14 01:06:45 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Wed Sep 28 17:29:17 2005 @@ -158,7 +158,7 @@ setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); - setOperationAction(ISD::SREM , MVT::f64 , Expand); + setOperationAction(ISD::FREM , MVT::f64 , Expand); setOperationAction(ISD::CTPOP , MVT::i8 , Expand); setOperationAction(ISD::CTTZ , MVT::i8 , Expand); setOperationAction(ISD::CTLZ , MVT::i8 , Expand); @@ -205,12 +205,12 @@ setOperationAction(ISD::FCOS , MVT::f64, Expand); setOperationAction(ISD::FABS , MVT::f64, Expand); setOperationAction(ISD::FNEG , MVT::f64, Expand); - setOperationAction(ISD::SREM , MVT::f64, Expand); + setOperationAction(ISD::FREM , MVT::f64, Expand); setOperationAction(ISD::FSIN , MVT::f32, Expand); setOperationAction(ISD::FCOS , MVT::f32, Expand); setOperationAction(ISD::FABS , MVT::f32, Expand); setOperationAction(ISD::FNEG , MVT::f32, Expand); - setOperationAction(ISD::SREM , MVT::f32, Expand); + setOperationAction(ISD::FREM , MVT::f32, Expand); addLegalFPImmediate(+0.0); // xorps / xorpd } else { @@ -2513,6 +2513,7 @@ } return Result; + case ISD::FADD: case ISD::ADD: Op0 = N.getOperand(0); Op1 = N.getOperand(1); @@ -2703,6 +2704,8 @@ return Result; } + case ISD::FSUB: + case ISD::FMUL: case ISD::SUB: case ISD::MUL: case ISD::AND: @@ -2810,7 +2813,9 @@ } switch (Node->getOpcode()) { default: assert(0 && "Unreachable!"); + case ISD::FSUB: case ISD::SUB: Opc = X86ScalarSSE ? SSE_SUBTab[Opc] : SUBTab[Opc]; break; + case ISD::FMUL: case ISD::MUL: Opc = X86ScalarSSE ? SSE_MULTab[Opc] : MULTab[Opc]; break; case ISD::AND: Opc = ANDTab[Opc]; break; case ISD::OR: Opc = ORTab[Opc]; break; @@ -2824,7 +2829,7 @@ } if (isFoldableLoad(Op0, Op1, true)) - if (Node->getOpcode() != ISD::SUB) { + if (Node->getOpcode() != ISD::SUB && Node->getOpcode() != ISD::FSUB) { std::swap(Op0, Op1); goto FoldOps; } else { @@ -2860,7 +2865,9 @@ } switch (Node->getOpcode()) { default: assert(0 && "Unreachable!"); + case ISD::FSUB: case ISD::SUB: Opc = X86ScalarSSE ? SSE_SUBTab[Opc] : SUBTab[Opc]; break; + case ISD::FMUL: case ISD::MUL: Opc = X86ScalarSSE ? SSE_MULTab[Opc] : MULTab[Opc]; break; case ISD::AND: Opc = ANDTab[Opc]; break; case ISD::OR: Opc = ORTab[Opc]; break; @@ -2902,7 +2909,9 @@ } switch (Node->getOpcode()) { default: assert(0 && "Unreachable!"); + case ISD::FSUB: case ISD::SUB: Opc = X86ScalarSSE ? SSE_SUBTab[Opc] : SUBTab[Opc]; break; + case ISD::FMUL: case ISD::MUL: Opc = X86ScalarSSE ? SSE_MULTab[Opc] : MULTab[Opc]; break; case ISD::AND: Opc = ANDTab[Opc]; break; case ISD::OR: Opc = ORTab[Opc]; break; @@ -3006,6 +3015,8 @@ N.getValueType(), Result); return Result; + case ISD::FDIV: + case ISD::FREM: case ISD::SDIV: case ISD::UDIV: case ISD::SREM: @@ -3013,7 +3024,7 @@ assert((N.getOpcode() != ISD::SREM || MVT::isInteger(N.getValueType())) && "We don't support this operator!"); - if (N.getOpcode() == ISD::SDIV) { + if (N.getOpcode() == ISD::SDIV || N.getOpcode() == ISD::FDIV) { // We can fold loads into FpDIVs, but not really into any others. if (N.getValueType() == MVT::f64 && !X86ScalarSSE) { // Check for reversed and unreversed DIV. @@ -3756,9 +3767,12 @@ default: std::cerr << "CANNOT [mem] op= val: "; StVal.Val->dump(); std::cerr << "\n"; + case ISD::FMUL: case ISD::MUL: + case ISD::FDIV: case ISD::SDIV: case ISD::UDIV: + case ISD::FREM: case ISD::SREM: case ISD::UREM: return false; @@ -3837,7 +3851,8 @@ // If we have [mem] = V op [mem], try to turn it into: // [mem] = [mem] op V. - if (Op1 == TheLoad && StVal.getOpcode() != ISD::SUB && + if (Op1 == TheLoad && + StVal.getOpcode() != ISD::SUB && StVal.getOpcode() != ISD::FSUB && StVal.getOpcode() != ISD::SHL && StVal.getOpcode() != ISD::SRA && StVal.getOpcode() != ISD::SRL) std::swap(Op0, Op1); From lattner at cs.uiuc.edu Wed Sep 28 17:29:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 17:29:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelLowering.cpp AlphaISelPattern.cpp Message-ID: <200509282229.RAA29174@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelLowering.cpp updated: 1.4 -> 1.5 AlphaISelPattern.cpp updated: 1.170 -> 1.171 --- Log message: Add FP versions of the binary operators, keeping the int and fp worlds seperate. Though I have done extensive testing, it is possible that this will break things in configs I can't test. Please let me know if this causes a problem and I'll fix it ASAP. --- Diffs of the changes: (+22 -33) AlphaISelLowering.cpp | 4 +-- AlphaISelPattern.cpp | 51 +++++++++++++++++++------------------------------- 2 files changed, 22 insertions(+), 33 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelLowering.cpp diff -u llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.4 llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.5 --- llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.4 Tue Sep 13 14:03:13 2005 +++ llvm/lib/Target/Alpha/AlphaISelLowering.cpp Wed Sep 28 17:29:17 2005 @@ -68,8 +68,8 @@ setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); setOperationAction(ISD::SEXTLOAD, MVT::i16, Expand); - setOperationAction(ISD::SREM, MVT::f32, Expand); - setOperationAction(ISD::SREM, MVT::f64, Expand); + setOperationAction(ISD::FREM, MVT::f32, Expand); + setOperationAction(ISD::FREM, MVT::f64, Expand); setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.170 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.171 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.170 Tue Sep 13 14:31:44 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Wed Sep 28 17:29:17 2005 @@ -1275,10 +1275,7 @@ case ISD::SHL: Opc = Alpha::SL; break; case ISD::SRL: Opc = Alpha::SRL; break; case ISD::SRA: Opc = Alpha::SRA; break; - case ISD::MUL: - Opc = isFP ? (DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS) - : Alpha::MULQ; - break; + case ISD::MUL: Opc = Alpha::MULQ; break; }; Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); @@ -1288,25 +1285,7 @@ case ISD::ADD: case ISD::SUB: - if (isFP) { - ConstantFPSDNode *CN; - if (opcode == ISD::ADD) - Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS; - else - Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS; - if (opcode == ISD::SUB - && (CN = dyn_cast(N.getOperand(0))) - && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0))) - { - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Tmp2).addReg(Tmp2); - } else { - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); - } - return Result; - } else { + { bool isAdd = opcode == ISD::ADD; //first check for Scaled Adds and Subs! @@ -1369,15 +1348,25 @@ } return Result; } - + case ISD::FADD: + case ISD::FSUB: + case ISD::FMUL: + case ISD::FDIV: { + if (opcode == ISD::FADD) + Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS; + else if (opcode == ISD::FSUB) + Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS; + else if (opcode == ISD::FMUL) + Opc = DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS; + else + Opc = DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + } case ISD::SDIV: - if (isFP) { - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS, 2, Result) - .addReg(Tmp1).addReg(Tmp2); - return Result; - } else { + { //check if we can convert into a shift! if (isSIntImmediate(N.getOperand(1), SImm) && SImm != 0 && isPowerOf2_64(llabs(SImm))) { From lattner at cs.uiuc.edu Wed Sep 28 17:30:10 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 17:30:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp PPC32ISelLowering.cpp PPC32ISelPattern.cpp Message-ID: <200509282230.RAA29248@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.81 -> 1.82 PPC32ISelLowering.cpp updated: 1.26 -> 1.27 PPC32ISelPattern.cpp updated: 1.178 -> 1.179 --- Log message: Add FP versions of the binary operators, keeping the int and fp worlds seperate. --- Diffs of the changes: (+120 -114) PPC32ISelDAGToDAG.cpp | 74 ++++++++++++------------- PPC32ISelLowering.cpp | 12 ++-- PPC32ISelPattern.cpp | 148 ++++++++++++++++++++++++++------------------------ 3 files changed, 120 insertions(+), 114 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.81 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.82 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.81 Wed Sep 28 13:12:37 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Wed Sep 28 17:29:58 2005 @@ -767,22 +767,20 @@ CurDAG->SelectNodeTo(N, PPC::FCTIWZ, N->getValueType(0), Select(N->getOperand(0))); return SDOperand(N, 0); - case ISD::ADD: { - MVT::ValueType Ty = N->getValueType(0); - if (Ty == MVT::i32) { - if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1), - PPC::ADDIS, PPC::ADDI, true)) { - CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); - N = I; - } else { - CurDAG->SelectNodeTo(N, PPC::ADD, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - } - return SDOperand(N, 0); + case ISD::ADD: + if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1), + PPC::ADDIS, PPC::ADDI, true)) { + CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); + N = I; + } else { + CurDAG->SelectNodeTo(N, PPC::ADD, MVT::i32, Select(N->getOperand(0)), + Select(N->getOperand(1))); } - + return SDOperand(N, 0); + case ISD::FADD: { + MVT::ValueType Ty = N->getValueType(0); if (!NoExcessFPPrecision) { // Match FMA ops - if (N->getOperand(0).getOpcode() == ISD::MUL && + if (N->getOperand(0).getOpcode() == ISD::FMUL && N->getOperand(0).Val->hasOneUse()) { ++FusedFP; // Statistic CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMADD : PPC::FMADDS, Ty, @@ -790,7 +788,7 @@ Select(N->getOperand(0).getOperand(1)), Select(N->getOperand(1))); return SDOperand(N, 0); - } else if (N->getOperand(1).getOpcode() == ISD::MUL && + } else if (N->getOperand(1).getOpcode() == ISD::FMUL && N->getOperand(1).hasOneUse()) { ++FusedFP; // Statistic CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMADD : PPC::FMADDS, Ty, @@ -806,30 +804,30 @@ return SDOperand(N, 0); } case ISD::SUB: { - MVT::ValueType Ty = N->getValueType(0); - if (Ty == MVT::i32) { - unsigned Imm; - if (isIntImmediate(N->getOperand(0), Imm) && isInt16(Imm)) { - if (0 == Imm) - CurDAG->SelectNodeTo(N, PPC::NEG, Ty, Select(N->getOperand(1))); - else - CurDAG->SelectNodeTo(N, PPC::SUBFIC, Ty, Select(N->getOperand(1)), - getI32Imm(Lo16(Imm))); - return SDOperand(N, 0); - } - if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1), - PPC::ADDIS, PPC::ADDI, true, true)) { - CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); - N = I; - } else { - CurDAG->SelectNodeTo(N, PPC::SUBF, Ty, Select(N->getOperand(1)), - Select(N->getOperand(0))); - } + unsigned Imm; + if (isIntImmediate(N->getOperand(0), Imm) && isInt16(Imm)) { + if (0 == Imm) + CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, Select(N->getOperand(1))); + else + CurDAG->SelectNodeTo(N, PPC::SUBFIC, MVT::i32, Select(N->getOperand(1)), + getI32Imm(Lo16(Imm))); return SDOperand(N, 0); } + if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1), + PPC::ADDIS, PPC::ADDI, true, true)) { + CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); + N = I; + } else { + CurDAG->SelectNodeTo(N, PPC::SUBF, MVT::i32, Select(N->getOperand(1)), + Select(N->getOperand(0))); + } + return SDOperand(N, 0); + } + case ISD::FSUB: { + MVT::ValueType Ty = N->getValueType(0); if (!NoExcessFPPrecision) { // Match FMA ops - if (N->getOperand(0).getOpcode() == ISD::MUL && + if (N->getOperand(0).getOpcode() == ISD::FMUL && N->getOperand(0).Val->hasOneUse()) { ++FusedFP; // Statistic CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS, Ty, @@ -837,7 +835,7 @@ Select(N->getOperand(0).getOperand(1)), Select(N->getOperand(1))); return SDOperand(N, 0); - } else if (N->getOperand(1).getOpcode() == ISD::MUL && + } else if (N->getOperand(1).getOpcode() == ISD::FMUL && N->getOperand(1).Val->hasOneUse()) { ++FusedFP; // Statistic CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS, Ty, @@ -852,6 +850,7 @@ Select(N->getOperand(1))); return SDOperand(N, 0); } + case ISD::FMUL: case ISD::MUL: { unsigned Imm, Opc; if (isIntImmediate(N->getOperand(1), Imm) && isInt16(Imm)) { @@ -869,7 +868,8 @@ Select(N->getOperand(1))); return SDOperand(N, 0); } - case ISD::SDIV: { + case ISD::SDIV: + case ISD::FDIV: { unsigned Imm; if (isIntImmediate(N->getOperand(1), Imm)) { if ((signed)Imm > 0 && isPowerOf2_32(Imm)) { Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.26 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.27 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.26 Tue Sep 27 17:18:25 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Wed Sep 28 17:29:58 2005 @@ -52,10 +52,10 @@ // We don't support sin/cos/sqrt/fmod setOperationAction(ISD::FSIN , MVT::f64, Expand); setOperationAction(ISD::FCOS , MVT::f64, Expand); - setOperationAction(ISD::SREM , MVT::f64, Expand); + setOperationAction(ISD::FREM , MVT::f64, Expand); setOperationAction(ISD::FSIN , MVT::f32, Expand); setOperationAction(ISD::FCOS , MVT::f32, Expand); - setOperationAction(ISD::SREM , MVT::f32, Expand); + setOperationAction(ISD::FREM , MVT::f32, Expand); // If we're enabling GP optimizations, use hardware square root if (!TM.getSubtarget().hasFSQRT()) { @@ -208,19 +208,19 @@ case ISD::SETULT: case ISD::SETLT: return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), FV, TV); + DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS), FV, TV); case ISD::SETUGE: case ISD::SETGE: return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), TV, FV); + DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS), TV, FV); case ISD::SETUGT: case ISD::SETGT: return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), FV, TV); + DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS), FV, TV); case ISD::SETULE: case ISD::SETLE: return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), TV, FV); + DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS), TV, FV); } break; } Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.178 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.179 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.178 Fri Sep 9 19:21:05 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Wed Sep 28 17:29:58 2005 @@ -1133,40 +1133,40 @@ return Result; case ISD::ADD: - if (!MVT::isInteger(DestType)) { - if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL && - N.getOperand(0).Val->hasOneUse()) { - ++FusedFP; // Statistic - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); - Tmp3 = SelectExpr(N.getOperand(1)); - Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS; - BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); - return Result; - } - if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::MUL && - N.getOperand(1).Val->hasOneUse()) { - ++FusedFP; // Statistic - Tmp1 = SelectExpr(N.getOperand(1).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1).getOperand(1)); - Tmp3 = SelectExpr(N.getOperand(0)); - Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS; - BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); - return Result; - } - Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS; - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); - return Result; - } if (SelectIntImmediateExpr(N, Result, PPC::ADDIS, PPC::ADDI, true)) return Result; Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); BuildMI(BB, PPC::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; - + + case ISD::FADD: + if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::FMUL && + N.getOperand(0).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(1)); + Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; + } + if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::FMUL && + N.getOperand(1).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(1).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(0)); + Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; + } + Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::AND: if (isIntImmediate(N.getOperand(1), Tmp2)) { if (isShiftedMask_32(Tmp2) || isShiftedMask_32(~Tmp2)) { @@ -1290,34 +1290,33 @@ return Result; } - case ISD::SUB: - if (!MVT::isInteger(DestType)) { - if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL && - N.getOperand(0).Val->hasOneUse()) { - ++FusedFP; // Statistic - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); - Tmp3 = SelectExpr(N.getOperand(1)); - Opc = DestType == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS; - BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); - return Result; - } - if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::MUL && - N.getOperand(1).Val->hasOneUse()) { - ++FusedFP; // Statistic - Tmp1 = SelectExpr(N.getOperand(1).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1).getOperand(1)); - Tmp3 = SelectExpr(N.getOperand(0)); - Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS; - BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); - return Result; - } - Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS; - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + case ISD::FSUB: + if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::FMUL && + N.getOperand(0).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(1)); + Opc = DestType == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; } + if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::FMUL && + N.getOperand(1).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(1).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(0)); + Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; + } + Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::SUB: if (isIntImmediate(N.getOperand(0), Tmp1) && isInt16(Tmp1)) { Tmp1 = Lo16(Tmp1); Tmp2 = SelectExpr(N.getOperand(1)); @@ -1334,6 +1333,13 @@ BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1); return Result; + case ISD::FMUL: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, DestType == MVT::f32 ? PPC::FMULS : PPC::FMUL, 2, + Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::MUL: Tmp1 = SelectExpr(N.getOperand(0)); if (isIntImmediate(N.getOperand(1), Tmp2) && isInt16(Tmp2)) { @@ -1341,13 +1347,7 @@ BuildMI(BB, PPC::MULLI, 2, Result).addReg(Tmp1).addSImm(Tmp2); } else { Tmp2 = SelectExpr(N.getOperand(1)); - switch (DestType) { - default: assert(0 && "Unknown type to ISD::MUL"); break; - case MVT::i32: Opc = PPC::MULLW; break; - case MVT::f32: Opc = PPC::FMULS; break; - case MVT::f64: Opc = PPC::FMUL; break; - } - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + BuildMI(BB, PPC::MULLW, 2, Result).addReg(Tmp1).addReg(Tmp2); } return Result; @@ -1359,6 +1359,17 @@ BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; + case ISD::FDIV: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + switch (DestType) { + default: assert(0 && "Unknown type to ISD::FDIV"); break; + case MVT::f32: Opc = PPC::FDIVS; break; + case MVT::f64: Opc = PPC::FDIV; break; + } + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::SDIV: if (isIntImmediate(N.getOperand(1), Tmp3)) { if ((signed)Tmp3 > 0 && isPowerOf2_32(Tmp3)) { @@ -1392,12 +1403,7 @@ } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); - switch (DestType) { - default: assert(0 && "Unknown type to ISD::DIV"); break; - case MVT::i32: Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW; break; - case MVT::f32: Opc = PPC::FDIVS; break; - case MVT::f64: Opc = PPC::FDIV; break; - } + Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW; break; BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; @@ -1624,9 +1630,9 @@ case ISD::FNEG: if (!NoExcessFPPrecision && - ISD::ADD == N.getOperand(0).getOpcode() && + ISD::FADD == N.getOperand(0).getOpcode() && N.getOperand(0).Val->hasOneUse() && - ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() && + ISD::FMUL == N.getOperand(0).getOperand(0).getOpcode() && N.getOperand(0).getOperand(0).Val->hasOneUse()) { ++FusedFP; // Statistic Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0)); @@ -1635,9 +1641,9 @@ Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS; BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); } else if (!NoExcessFPPrecision && - ISD::ADD == N.getOperand(0).getOpcode() && + ISD::FADD == N.getOperand(0).getOpcode() && N.getOperand(0).Val->hasOneUse() && - ISD::MUL == N.getOperand(0).getOperand(1).getOpcode() && + ISD::FMUL == N.getOperand(0).getOperand(1).getOpcode() && N.getOperand(0).getOperand(1).Val->hasOneUse()) { ++FusedFP; // Statistic Tmp1 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(0)); From lattner at cs.uiuc.edu Wed Sep 28 17:31:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 17:31:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp Message-ID: <200509282231.RAA29355@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ScalarEvolution.cpp updated: 1.42 -> 1.43 --- Log message: wrap a long line --- Diffs of the changes: (+2 -1) ScalarEvolution.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Analysis/ScalarEvolution.cpp diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.42 llvm/lib/Analysis/ScalarEvolution.cpp:1.43 --- llvm/lib/Analysis/ScalarEvolution.cpp:1.42 Mon Aug 15 19:37:01 2005 +++ llvm/lib/Analysis/ScalarEvolution.cpp Wed Sep 28 17:30:58 2005 @@ -100,7 +100,8 @@ cl::opt MaxBruteForceIterations("scalar-evolution-max-iterations", cl::ReallyHidden, - cl::desc("Maximum number of iterations SCEV will symbolically execute a constant derived loop"), + cl::desc("Maximum number of iterations SCEV will " + "symbolically execute a constant derived loop"), cl::init(100)); } From lattner at cs.uiuc.edu Wed Sep 28 17:38:38 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 17:38:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509282238.RAA29620@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.108 -> 1.109 --- Log message: Mark int binops as int-only, add FP binops. Mark FADD/FMUL as commutative but not associative. Add [SU]REM. --- Diffs of the changes: (+23 -15) PowerPCInstrInfo.td | 38 +++++++++++++++++++++++--------------- 1 files changed, 23 insertions(+), 15 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.108 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.109 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.108 Wed Sep 28 15:58:39 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Wed Sep 28 17:38:27 2005 @@ -65,14 +65,14 @@ } // Builtin profiles. -def SDTImm : SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. -def SDTVT : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt' -def SDTBinOp : SDTypeProfile<1, 2, [ // add, mul, etc. - SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2> -]>; -def SDTIntBinOp : SDTypeProfile<1, 2, [ // and, or, xor, udiv, etc. +def SDTImm : SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. +def SDTVT : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt' +def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc. SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0> ]>; +def SDTFPBinOp : SDTypeProfile<1, 2, [ // fadd, fmul, etc. + SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0> +]>; def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz SDTCisSameAs<0, 1>, SDTCisInt<0> ]>; @@ -106,21 +106,29 @@ def imm : SDNode<"ISD::Constant" , SDTImm , [], "ConstantSDNode">; def vt : SDNode<"ISD::VALUETYPE" , SDTVT , [], "VTSDNode">; +def add : SDNode<"ISD::ADD" , SDTIntBinOp , + [SDNPCommutative, SDNPAssociative]>; +def sub : SDNode<"ISD::SUB" , SDTIntBinOp>; +def mul : SDNode<"ISD::MUL" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; +def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp, [SDNPCommutative]>; +def mulhu : SDNode<"ISD::MULHU" , SDTIntBinOp, [SDNPCommutative]>; +def sdiv : SDNode<"ISD::SDIV" , SDTIntBinOp>; +def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; +def srem : SDNode<"ISD::SREM" , SDTIntBinOp>; +def urem : SDNode<"ISD::UREM" , SDTIntBinOp>; def and : SDNode<"ISD::AND" , SDTIntBinOp, [SDNPCommutative, SDNPAssociative]>; def or : SDNode<"ISD::OR" , SDTIntBinOp, [SDNPCommutative, SDNPAssociative]>; def xor : SDNode<"ISD::XOR" , SDTIntBinOp, [SDNPCommutative, SDNPAssociative]>; -def add : SDNode<"ISD::ADD" , SDTBinOp , - [SDNPCommutative, SDNPAssociative]>; -def sub : SDNode<"ISD::SUB" , SDTBinOp>; -def mul : SDNode<"ISD::MUL" , SDTBinOp , - [SDNPCommutative, SDNPAssociative]>; -def sdiv : SDNode<"ISD::SDIV" , SDTBinOp>; -def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; -def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp, [SDNPCommutative]>; -def mulhu : SDNode<"ISD::MULHU" , SDTIntBinOp, [SDNPCommutative]>; +def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>; +def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>; +def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; +def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>; +def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; + def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; From lattner at cs.uiuc.edu Wed Sep 28 17:47:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 17:47:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509282247.RAA30103@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.109 -> 1.110 --- Log message: add a patter for SUBFIC --- Diffs of the changes: (+1 -1) PowerPCInstrInfo.td | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.109 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.110 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.109 Wed Sep 28 17:38:27 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Wed Sep 28 17:47:06 2005 @@ -396,7 +396,7 @@ [(set GPRC:$rD, (mul GPRC:$rA, immSExt16:$imm))]>; def SUBFIC : DForm_2< 8, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), "subfic $rD, $rA, $imm", - []>; + [(set GPRC:$rD, (sub immSExt16:$imm, GPRC:$rA))]>; def LI : DForm_2_r0<14, (ops GPRC:$rD, s16imm:$imm), "li $rD, $imm", [(set GPRC:$rD, immSExt16:$imm)]>; From lattner at cs.uiuc.edu Wed Sep 28 17:47:40 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 17:47:40 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509282247.RAA30136@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.82 -> 1.83 --- Log message: Use the autogenerated matcher for ADD/SUB --- Diffs of the changes: (+0 -30) PPC32ISelDAGToDAG.cpp | 30 ------------------------------ 1 files changed, 30 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.82 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.83 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.82 Wed Sep 28 17:29:58 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Wed Sep 28 17:47:28 2005 @@ -767,16 +767,6 @@ CurDAG->SelectNodeTo(N, PPC::FCTIWZ, N->getValueType(0), Select(N->getOperand(0))); return SDOperand(N, 0); - case ISD::ADD: - if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1), - PPC::ADDIS, PPC::ADDI, true)) { - CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); - N = I; - } else { - CurDAG->SelectNodeTo(N, PPC::ADD, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - } - return SDOperand(N, 0); case ISD::FADD: { MVT::ValueType Ty = N->getValueType(0); if (!NoExcessFPPrecision) { // Match FMA ops @@ -803,26 +793,6 @@ Select(N->getOperand(0)), Select(N->getOperand(1))); return SDOperand(N, 0); } - case ISD::SUB: { - unsigned Imm; - if (isIntImmediate(N->getOperand(0), Imm) && isInt16(Imm)) { - if (0 == Imm) - CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, Select(N->getOperand(1))); - else - CurDAG->SelectNodeTo(N, PPC::SUBFIC, MVT::i32, Select(N->getOperand(1)), - getI32Imm(Lo16(Imm))); - return SDOperand(N, 0); - } - if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1), - PPC::ADDIS, PPC::ADDI, true, true)) { - CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); - N = I; - } else { - CurDAG->SelectNodeTo(N, PPC::SUBF, MVT::i32, Select(N->getOperand(1)), - Select(N->getOperand(0))); - } - return SDOperand(N, 0); - } case ISD::FSUB: { MVT::ValueType Ty = N->getValueType(0); From lattner at cs.uiuc.edu Wed Sep 28 17:50:36 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 17:50:36 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509282250.RAA30202@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.83 -> 1.84 --- Log message: disentangle FP from INT versions of div/mul --- Diffs of the changes: (+16 -18) PPC32ISelDAGToDAG.cpp | 34 ++++++++++++++++------------------ 1 files changed, 16 insertions(+), 18 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.83 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.84 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.83 Wed Sep 28 17:47:28 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Wed Sep 28 17:50:24 2005 @@ -820,7 +820,6 @@ Select(N->getOperand(1))); return SDOperand(N, 0); } - case ISD::FMUL: case ISD::MUL: { unsigned Imm, Opc; if (isIntImmediate(N->getOperand(1), Imm) && isInt16(Imm)) { @@ -828,18 +827,17 @@ Select(N->getOperand(0)), getI32Imm(Lo16(Imm))); return SDOperand(N, 0); } - switch (N->getValueType(0)) { - default: assert(0 && "Unhandled multiply type!"); - case MVT::i32: Opc = PPC::MULLW; break; - case MVT::f32: Opc = PPC::FMULS; break; - case MVT::f64: Opc = PPC::FMUL; break; - } - CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), + CurDAG->SelectNodeTo(N, PPC::MULLW, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); return SDOperand(N, 0); } - case ISD::SDIV: - case ISD::FDIV: { + case ISD::FMUL: { + unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FMULS : PPC::FMUL; + CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), + Select(N->getOperand(1))); + return SDOperand(N, 0); + } + case ISD::SDIV: { unsigned Imm; if (isIntImmediate(N->getOperand(1), Imm)) { if ((signed)Imm > 0 && isPowerOf2_32(Imm)) { @@ -869,17 +867,17 @@ } } - unsigned Opc; - switch (N->getValueType(0)) { - default: assert(0 && "Unknown type to ISD::SDIV"); - case MVT::i32: Opc = PPC::DIVW; break; - case MVT::f32: Opc = PPC::FDIVS; break; - case MVT::f64: Opc = PPC::FDIV; break; - } - CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), + CurDAG->SelectNodeTo(N, PPC::DIVW, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); return SDOperand(N, 0); } + case ISD::FDIV: { + unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FDIVS : PPC::FDIV; + CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), + Select(N->getOperand(1))); + return SDOperand(N, 0); + } + case ISD::UDIV: { // If this is a divide by constant, we can emit code using some magic // constants to implement it as a multiply instead. From lattner at cs.uiuc.edu Wed Sep 28 17:53:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 17:53:28 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509282253.RAA30263@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.84 -> 1.85 --- Log message: Autogen MUL, move FP cases together --- Diffs of the changes: (+12 -24) PPC32ISelDAGToDAG.cpp | 36 ++++++++++++------------------------ 1 files changed, 12 insertions(+), 24 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.84 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.85 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.84 Wed Sep 28 17:50:24 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Wed Sep 28 17:53:16 2005 @@ -820,23 +820,6 @@ Select(N->getOperand(1))); return SDOperand(N, 0); } - case ISD::MUL: { - unsigned Imm, Opc; - if (isIntImmediate(N->getOperand(1), Imm) && isInt16(Imm)) { - CurDAG->SelectNodeTo(N, PPC::MULLI, MVT::i32, - Select(N->getOperand(0)), getI32Imm(Lo16(Imm))); - return SDOperand(N, 0); - } - CurDAG->SelectNodeTo(N, PPC::MULLW, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); - } - case ISD::FMUL: { - unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FMULS : PPC::FMUL; - CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); - } case ISD::SDIV: { unsigned Imm; if (isIntImmediate(N->getOperand(1), Imm)) { @@ -871,13 +854,6 @@ Select(N->getOperand(1))); return SDOperand(N, 0); } - case ISD::FDIV: { - unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FDIVS : PPC::FDIV; - CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); - } - case ISD::UDIV: { // If this is a divide by constant, we can emit code using some magic // constants to implement it as a multiply instead. @@ -997,6 +973,18 @@ Select(N->getOperand(1))); return SDOperand(N, 0); } + case ISD::FMUL: { + unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FMULS : PPC::FMUL; + CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), + Select(N->getOperand(1))); + return SDOperand(N, 0); + } + case ISD::FDIV: { + unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FDIVS : PPC::FDIV; + CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), + Select(N->getOperand(1))); + return SDOperand(N, 0); + } case ISD::FABS: CurDAG->SelectNodeTo(N, PPC::FABS, N->getValueType(0), Select(N->getOperand(0))); From lattner at cs.uiuc.edu Wed Sep 28 18:03:22 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 18:03:22 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/fold-li.ll Message-ID: <200509282303.SAA30367@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: fold-li.ll added (r1.1) --- Log message: add a testcase for a feature we regressed on because noone wrote the test! :( --- Diffs of the changes: (+14 -0) fold-li.ll | 14 ++++++++++++++ 1 files changed, 14 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/fold-li.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/fold-li.ll:1.1 *** /dev/null Wed Sep 28 18:03:21 2005 --- llvm/test/Regression/CodeGen/PowerPC/fold-li.ll Wed Sep 28 18:03:11 2005 *************** *** 0 **** --- 1,14 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 && + ; RUN: llvm-as < %s | llc -march=ppc32 | grep -v align | not grep li + + ;; Test that immediates are folded into these instructions correctly. + + int %ADD(int %X) { + %Y = add int %X, 65537 + ret int %Y + } + + int %SUB(int %X) { + %Y = sub int %X, 65537 + ret int %Y + } From lattner at cs.uiuc.edu Wed Sep 28 18:07:24 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 18:07:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509282307.SAA30431@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.110 -> 1.111 --- Log message: Codegen ADD X, IMM -> addis/addi if needed. This implements PowerPC/fold-li.ll --- Diffs of the changes: (+12 -2) PowerPCInstrInfo.td | 14 ++++++++++++-- 1 files changed, 12 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.110 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.111 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.110 Wed Sep 28 17:47:06 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Wed Sep 28 18:07:13 2005 @@ -218,6 +218,13 @@ return getI32Imm((unsigned)N->getValue() >> 16); }]>; +def HA16 : SDNodeXFormgetValue(); + return getI32Imm((Val - (signed short)Val) >> 16); +}]>; + + def immSExt16 : PatLeaf<(imm), [{ // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended // field. Used by instructions like 'addi'. @@ -801,10 +808,13 @@ def EQV2 : Pat<(xor GPRC:$in1, (not GPRC:$in2)), (EQV GPRC:$in1, GPRC:$in2)>; -// or by an arbitrary immediate. +// ADD an arbitrary immediate. +def : Pat<(add GPRC:$in, imm:$imm), + (ADDIS (ADDI GPRC:$in, (LO16 imm:$imm)), (HA16 imm:$imm))>; +// OR an arbitrary immediate. def : Pat<(or GPRC:$in, imm:$imm), (ORIS (ORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>; -// xor by an arbitrary immediate. +// XOR an arbitrary immediate. def : Pat<(xor GPRC:$in, imm:$imm), (XORIS (XORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>; From lattner at cs.uiuc.edu Wed Sep 28 19:59:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 19:59:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509290059.TAA31188@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.85 -> 1.86 --- Log message: Never rely on ReplaceAllUsesWith when selecting, use CodeGenMap instead. ReplaceAllUsesWith does not replace scalars SDOperand floating around on the stack, permitting things to be selected multiple times. --- Diffs of the changes: (+29 -34) PPC32ISelDAGToDAG.cpp | 63 +++++++++++++++++++++++--------------------------- 1 files changed, 29 insertions(+), 34 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.85 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.86 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.85 Wed Sep 28 17:53:16 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Wed Sep 28 19:59:32 2005 @@ -637,6 +637,10 @@ if (N->getOpcode() >= ISD::BUILTIN_OP_END && N->getOpcode() < PPCISD::FIRST_NUMBER) return Op; // Already selected. + + // If this has already been converted, use it. + std::map::iterator CGMI = CodeGenMap.find(Op); + if (CGMI != CodeGenMap.end()) return CGMI->second; switch (N->getOpcode()) { default: break; @@ -653,11 +657,8 @@ New = CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops); } - if (New.Val != N) { - CurDAG->ReplaceAllUsesWith(Op, New); - N = New.Val; - } - return SDOperand(N, 0); + if (!N->hasOneUse()) CodeGenMap[Op] = New; + return New; } case ISD::CopyFromReg: { SDOperand Chain = Select(N->getOperand(0)); @@ -670,13 +671,10 @@ SDOperand Chain = Select(N->getOperand(0)); SDOperand Reg = N->getOperand(1); SDOperand Val = Select(N->getOperand(2)); - if (Chain != N->getOperand(0) || Val != N->getOperand(2)) { - SDOperand New = CurDAG->getNode(ISD::CopyToReg, MVT::Other, - Chain, Reg, Val); - CurDAG->ReplaceAllUsesWith(Op, New); - N = New.Val; - } - return SDOperand(N, 0); + SDOperand New = CurDAG->getNode(ISD::CopyToReg, MVT::Other, + Chain, Reg, Val); + if (!N->hasOneUse()) CodeGenMap[Op] = New; + return New; } case ISD::UNDEF: if (N->getValueType(0) == MVT::i32) @@ -746,7 +744,8 @@ Result = CurDAG->getCopyFromReg(Chain, PPC::R1, MVT::i32); // Finally, replace the DYNAMIC_STACKALLOC with the copyfromreg. - CurDAG->ReplaceAllUsesWith(N, Result.Val); + CodeGenMap[Op.getValue(0)] = Result; + CodeGenMap[Op.getValue(1)] = Result.getValue(1); return SDOperand(Result.Val, Op.ResNo); } case PPCISD::FSEL: @@ -843,10 +842,8 @@ return SDOperand(N, 0); } else if (Imm) { SDOperand Result = Select(BuildSDIVSequence(N)); - assert(Result.ResNo == 0); - CurDAG->ReplaceAllUsesWith(Op, Result); - N = Result.Val; - return SDOperand(N, 0); + CodeGenMap[Op] = Result; + return Result; } } @@ -860,10 +857,8 @@ unsigned Imm; if (isIntImmediate(N->getOperand(1), Imm) && Imm) { SDOperand Result = Select(BuildUDIVSequence(N)); - assert(Result.ResNo == 0); - CurDAG->ReplaceAllUsesWith(Op, Result); - N = Result.Val; - return SDOperand(N, 0); + CodeGenMap[Op] = Result; + return Result; } CurDAG->SelectNodeTo(N, PPC::DIVWU, MVT::i32, Select(N->getOperand(0)), @@ -903,18 +898,14 @@ return SDOperand(N, 0); } case ISD::OR: - if (SDNode *I = SelectBitfieldInsert(N)) { - CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); - N = I; - return SDOperand(N, 0); - } + if (SDNode *I = SelectBitfieldInsert(N)) + return CodeGenMap[Op] = SDOperand(I, 0); + if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1), - PPC::ORIS, PPC::ORI)) { - CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); - N = I; - return SDOperand(N, 0); - } + PPC::ORIS, PPC::ORI)) + return CodeGenMap[Op] = SDOperand(I, 0); + // Finally, check for the case where we are being asked to select // 'or (not(a), b)' or 'or (a, not(b))' which can be selected as orc. if (isOprNot(N->getOperand(0).Val)) @@ -1073,7 +1064,9 @@ Select(N->getOperand(3)), CarryFromLo); Result.push_back(CarryFromLo.getValue(0)); Result.push_back(ResultHi); - CurDAG->ReplaceAllUsesWith(N, Result); + + CodeGenMap[Op.getValue(0)] = Result[0]; + CodeGenMap[Op.getValue(1)] = Result[1]; return Result[Op.ResNo]; } case ISD::SUB_PARTS: { @@ -1087,7 +1080,8 @@ RHSL, LHSL)); Result.push_back(CurDAG->getTargetNode(PPC::SUBFE, MVT::i32, RHSH, LHSH, Result[0].getValue(1))); - CurDAG->ReplaceAllUsesWith(N, Result); + CodeGenMap[Op.getValue(0)] = Result[0]; + CodeGenMap[Op.getValue(1)] = Result[1]; return Result[Op.ResNo]; } @@ -1395,7 +1389,8 @@ } CallResults.push_back(Chain); - CurDAG->ReplaceAllUsesWith(N, CallResults); + for (unsigned i = 0, e = CallResults.size(); i != e; ++i) + CodeGenMap[Op.getValue(i)] = CallResults[i]; return CallResults[Op.ResNo]; } case ISD::RET: { From jeffc at jolt-lang.org Wed Sep 28 21:00:01 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Wed, 28 Sep 2005 21:00:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200509290200.VAA31498@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.24 -> 1.25 --- Log message: Silence VC++ redeclaration warnings. --- Diffs of the changes: (+6 -4) ScheduleDAG.cpp | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.24 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.25 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.24 Tue Sep 27 12:32:45 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Wed Sep 28 20:59:49 2005 @@ -548,7 +548,8 @@ unsigned Slot = NotFound; // Compare against those previously scheduled operands - for (unsigned j = i + 1; j < N; j++) { + unsigned j = i + 1; + for (; j < N; j++) { // Get following instruction ScheduleInfo *Other = Ordering[j]; @@ -573,7 +574,7 @@ SI->Slot = Slot; // Insert sort based on slot - unsigned j = i + 1; + j = i + 1; for (; j < N; j++) { // Get following instruction ScheduleInfo *Other = Ordering[j]; @@ -602,7 +603,8 @@ unsigned Slot = NotFound; // Compare against those previously scheduled operands - for (unsigned j = i; 0 < j--;) { + unsigned j = i; + for (; 0 < j--;) { // Get following instruction ScheduleInfo *Other = Ordering[j]; @@ -627,7 +629,7 @@ SI->Slot = Slot; // Insert sort based on slot - unsigned j = i; + j = i; for (; 0 < j--;) { // Get following instruction ScheduleInfo *Other = Ordering[j]; From lattner at cs.uiuc.edu Wed Sep 28 23:54:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 28 Sep 2005 23:54:32 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Message-ID: <200509290454.XAA00535@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: SimplifyLibCalls.cpp updated: 1.51 -> 1.52 --- Log message: Implement a couple of memcmp folds from the todo list --- Diffs of the changes: (+121 -3) SimplifyLibCalls.cpp | 124 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 121 insertions(+), 3 deletions(-) Index: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp diff -u llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.51 llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.52 --- llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.51 Sun Sep 25 02:06:48 2005 +++ llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Wed Sep 28 23:54:20 2005 @@ -976,6 +976,127 @@ } } StrLenOptimizer; +/// IsOnlyUsedInEqualsComparison - Return true if it only matters that the value +/// is equal or not-equal to zero. +static bool IsOnlyUsedInEqualsZeroComparison(Instruction *I) { + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); + UI != E; ++UI) { + Instruction *User = cast(*UI); + if (User->getOpcode() == Instruction::SetNE || + User->getOpcode() == Instruction::SetEQ) { + if (isa(User->getOperand(1)) && + cast(User->getOperand(1))->isNullValue()) + continue; + } else if (CastInst *CI = dyn_cast(User)) + if (CI->getType() == Type::BoolTy) + continue; + // Unknown instruction. + return false; + } + return true; +} + +/// This memcmpOptimization will simplify a call to the memcmp library +/// function. +struct memcmpOptimization : public LibCallOptimization { + /// @brief Default Constructor + memcmpOptimization() + : LibCallOptimization("memcmp", "Number of 'memcmp' calls simplified") {} + + /// @brief Make sure that the "memcmp" function has the right prototype + virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &TD) { + Function::const_arg_iterator AI = F->arg_begin(); + if (F->arg_size() != 3 || !isa(AI->getType())) return false; + if (!isa((++AI)->getType())) return false; + if (!(++AI)->getType()->isInteger()) return false; + if (!F->getReturnType()->isInteger()) return false; + return true; + } + + /// Because of alignment and instruction information that we don't have, we + /// leave the bulk of this to the code generators. + /// + /// Note that we could do much more if we could force alignment on otherwise + /// small aligned allocas, or if we could indicate that loads have a small + /// alignment. + virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &TD) { + Value *LHS = CI->getOperand(1), *RHS = CI->getOperand(2); + + // If the two operands are the same, return zero. + if (LHS == RHS) { + // memcmp(s,s,x) -> 0 + CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); + CI->eraseFromParent(); + return true; + } + + // Make sure we have a constant length. + ConstantInt *LenC = dyn_cast(CI->getOperand(3)); + if (!LenC) return false; + uint64_t Len = LenC->getRawValue(); + + // If the length is zero, this returns 0. + switch (Len) { + case 0: + // memcmp(s1,s2,0) -> 0 + CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); + CI->eraseFromParent(); + return true; + case 1: { + // memcmp(S1,S2,1) -> *(ubyte*)S1 - *(ubyte*)S2 + const Type *UCharPtr = PointerType::get(Type::UByteTy); + CastInst *Op1Cast = new CastInst(LHS, UCharPtr, LHS->getName(), CI); + CastInst *Op2Cast = new CastInst(RHS, UCharPtr, RHS->getName(), CI); + Value *S1V = new LoadInst(Op1Cast, LHS->getName()+".val", CI); + Value *S2V = new LoadInst(Op2Cast, RHS->getName()+".val", CI); + Value *RV = BinaryOperator::createSub(S1V, S2V, CI->getName()+".diff",CI); + if (RV->getType() != CI->getType()) + RV = new CastInst(RV, CI->getType(), RV->getName(), CI); + CI->replaceAllUsesWith(RV); + CI->eraseFromParent(); + return true; + } + case 2: + if (IsOnlyUsedInEqualsZeroComparison(CI)) { + // TODO: IF both are aligned, use a short load/compare. + + // memcmp(S1,S2,2) -> S1[0]-S2[0] | S1[1]-S2[1] iff only ==/!= 0 matters + const Type *UCharPtr = PointerType::get(Type::UByteTy); + CastInst *Op1Cast = new CastInst(LHS, UCharPtr, LHS->getName(), CI); + CastInst *Op2Cast = new CastInst(RHS, UCharPtr, RHS->getName(), CI); + Value *S1V1 = new LoadInst(Op1Cast, LHS->getName()+".val1", CI); + Value *S2V1 = new LoadInst(Op2Cast, RHS->getName()+".val1", CI); + Value *D1 = BinaryOperator::createSub(S1V1, S2V1, + CI->getName()+".d1", CI); + Constant *One = ConstantInt::get(Type::IntTy, 1); + Value *G1 = new GetElementPtrInst(Op1Cast, One, "next1v", CI); + Value *G2 = new GetElementPtrInst(Op2Cast, One, "next2v", CI); + Value *S1V2 = new LoadInst(G1, LHS->getName()+".val2", CI); + Value *S2V2 = new LoadInst(G1, RHS->getName()+".val2", CI); + Value *D2 = BinaryOperator::createSub(S1V2, S2V2, + CI->getName()+".d1", CI); + Value *Or = BinaryOperator::createOr(D1, D2, CI->getName()+".res", CI); + if (Or->getType() != CI->getType()) + Or = new CastInst(Or, CI->getType(), Or->getName(), CI); + CI->replaceAllUsesWith(Or); + CI->eraseFromParent(); + return true; + } + break; + default: + break; + } + + + + return false; + } +} memcmpOptimizer; + + + + + /// This LibCallOptimization will simplify a call to the memcpy library /// function by expanding it out to a single store of size 0, 1, 2, 4, or 8 /// bytes depending on the length of the string and the alignment. Additional @@ -1968,11 +2089,8 @@ // * lround(cnst) -> cnst' // // memcmp: -// * memcmp(s1,s2,0) -> 0 -// * memcmp(x,x,l) -> 0 // * memcmp(x,y,l) -> cnst // (if all arguments are constant and strlen(x) <= l and strlen(y) <= l) -// * memcmp(x,y,1) -> *x - *y // // memmove: // * memmove(d,s,l,a) -> memcpy(d,s,l,a) From lattner at cs.uiuc.edu Thu Sep 29 01:11:46 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 01:11:46 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/SimplifyLibCalls/memcmp.ll Message-ID: <200509290611.BAA00841@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/SimplifyLibCalls: memcmp.ll added (r1.1) --- Log message: add a new testcase --- Diffs of the changes: (+23 -0) memcmp.ll | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+) Index: llvm/test/Regression/Transforms/SimplifyLibCalls/memcmp.ll diff -c /dev/null llvm/test/Regression/Transforms/SimplifyLibCalls/memcmp.ll:1.1 *** /dev/null Thu Sep 29 01:11:44 2005 --- llvm/test/Regression/Transforms/SimplifyLibCalls/memcmp.ll Thu Sep 29 01:11:34 2005 *************** *** 0 **** --- 1,23 ---- + ; Test that the memcmpOptimizer works correctly + ; RUN: llvm-as < %s | opt -simplify-libcalls | llvm-dis | not grep 'call.*memcmp' && + ; RUN: llvm-as < %s | opt -simplify-libcalls -disable-output + + declare int %memcmp(sbyte*,sbyte*,int) + %h = constant [2 x sbyte] c"h\00" + %hel = constant [4 x sbyte] c"hel\00" + %hello_u = constant [8 x sbyte] c"hello_u\00" + + implementation + + void %test(sbyte *%P, sbyte *%Q, int %N, int* %IP, bool *%BP) { + %A = call int %memcmp(sbyte *%P, sbyte* %P, int %N) + volatile store int %A, int* %IP + %B = call int %memcmp(sbyte *%P, sbyte* %Q, int 0) + volatile store int %B, int* %IP + %C = call int %memcmp(sbyte *%P, sbyte* %Q, int 1) + volatile store int %C, int* %IP + %D = call int %memcmp(sbyte *%P, sbyte* %Q, int 2) + %E = seteq int %D, 0 + volatile store bool %E, bool* %BP + ret void + } From lattner at cs.uiuc.edu Thu Sep 29 01:16:22 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 01:16:22 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Message-ID: <200509290616.BAA00943@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: SimplifyLibCalls.cpp updated: 1.52 -> 1.53 --- Log message: remove a bunch of unneeded stuff, or self evident comments --- Diffs of the changes: (+6 -45) SimplifyLibCalls.cpp | 51 ++++++--------------------------------------------- 1 files changed, 6 insertions(+), 45 deletions(-) Index: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp diff -u llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.52 llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.53 --- llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.52 Wed Sep 28 23:54:20 2005 +++ llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Thu Sep 29 01:16:11 2005 @@ -383,7 +383,6 @@ { ExitInMainOptimization() : LibCallOptimization("exit", "Number of 'exit' calls simplified") {} - virtual ~ExitInMainOptimization() {} // Make sure the called function looks like exit (int argument, int return // type, external linkage, not varargs). @@ -451,8 +450,6 @@ "Number of 'strcat' calls simplified") {} public: - /// @breif Destructor - virtual ~StrCatOptimization() {} /// @brief Make sure that the "strcat" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) @@ -540,7 +537,6 @@ public: StrChrOptimization() : LibCallOptimization("strchr", "Number of 'strchr' calls simplified") {} - virtual ~StrChrOptimization() {} /// @brief Make sure that the "strchr" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) @@ -632,7 +628,6 @@ public: StrCmpOptimization() : LibCallOptimization("strcmp", "Number of 'strcmp' calls simplified") {} - virtual ~StrCmpOptimization() {} /// @brief Make sure that the "strcmp" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) @@ -719,7 +714,6 @@ public: StrNCmpOptimization() : LibCallOptimization("strncmp", "Number of 'strncmp' calls simplified") {} - virtual ~StrNCmpOptimization() {} /// @brief Make sure that the "strncmp" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) @@ -822,7 +816,6 @@ public: StrCpyOptimization() : LibCallOptimization("strcpy", "Number of 'strcpy' calls simplified") {} - virtual ~StrCpyOptimization() {} /// @brief Make sure that the "strcpy" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) @@ -910,7 +903,6 @@ { StrLenOptimization() : LibCallOptimization("strlen", "Number of 'strlen' calls simplified") {} - virtual ~StrLenOptimization() {} /// @brief Make sure that the "strlen" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) @@ -1113,8 +1105,6 @@ LLVMMemCpyOptimization(const char* fname, const char* desc) : LibCallOptimization(fname, desc) {} public: - /// @brief Destructor - virtual ~LLVMMemCpyOptimization() {} /// @brief Make sure that the "memcpy" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& TD) @@ -1199,8 +1189,6 @@ "Number of 'llvm.memset' calls simplified") {} public: - /// @brief Destructor - virtual ~LLVMMemSetOptimization() {} /// @brief Make sure that the "memset" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& TD) @@ -1307,9 +1295,6 @@ PowOptimization() : LibCallOptimization("pow", "Number of 'pow' calls simplified") {} - /// @brief Destructor - virtual ~PowOptimization() {} - /// @brief Make sure that the "pow" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) { @@ -1384,9 +1369,6 @@ FPrintFOptimization() : LibCallOptimization("fprintf", "Number of 'fprintf' calls simplified") {} - /// @brief Destructor - virtual ~FPrintFOptimization() {} - /// @brief Make sure that the "fprintf" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) { @@ -1520,9 +1502,6 @@ SPrintFOptimization() : LibCallOptimization("sprintf", "Number of 'sprintf' calls simplified") {} - /// @brief Destructor - virtual ~SPrintFOptimization() {} - /// @brief Make sure that the "fprintf" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) { @@ -1657,9 +1636,6 @@ PutsOptimization() : LibCallOptimization("fputs", "Number of 'fputs' calls simplified") {} - /// @brief Destructor - virtual ~PutsOptimization() {} - /// @brief Make sure that the "fputs" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) { @@ -1723,17 +1699,12 @@ /// This LibCallOptimization will simplify calls to the "isdigit" library /// function. It simply does range checks the parameter explicitly. /// @brief Simplify the isdigit library function. -struct IsDigitOptimization : public LibCallOptimization -{ +struct isdigitOptimization : public LibCallOptimization { public: - /// @brief Default Constructor - IsDigitOptimization() : LibCallOptimization("isdigit", + isdigitOptimization() : LibCallOptimization("isdigit", "Number of 'isdigit' calls simplified") {} - /// @brief Destructor - virtual ~IsDigitOptimization() {} - - /// @brief Make sure that the "fputs" function has the right prototype + /// @brief Make sure that the "isdigit" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) { // Just make sure this has 1 argument @@ -1772,7 +1743,9 @@ ci->eraseFromParent(); return true; } -} IsDigitOptimizer; +} isdigitOptimizer; + + /// This LibCallOptimization will simplify calls to the "toascii" library /// function. It simply does the corresponding and operation to restrict the @@ -1785,9 +1758,6 @@ ToAsciiOptimization() : LibCallOptimization("toascii", "Number of 'toascii' calls simplified") {} - /// @brief Destructor - virtual ~ToAsciiOptimization() {} - /// @brief Make sure that the "fputs" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) { @@ -1826,9 +1796,6 @@ FFSOptimization() : LibCallOptimization("ffs", "Number of 'ffs' calls simplified") {} - /// @brief Destructor - virtual ~FFSOptimization() {} - /// @brief Make sure that the "fputs" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) { @@ -2070,12 +2037,6 @@ // exp, expf, expl: // * exp(log(x)) -> x // -// isascii: -// * isascii(c) -> ((c & ~0x7f) == 0) -// -// isdigit: -// * isdigit(c) -> (unsigned)(c) - '0' <= 9 -// // log, logf, logl: // * log(exp(x)) -> x // * log(x**y) -> y*log(x) From lattner at cs.uiuc.edu Thu Sep 29 01:16:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 01:16:48 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/SimplifyLibCalls/IsDigit.ll Message-ID: <200509290616.BAA01014@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/SimplifyLibCalls: IsDigit.ll updated: 1.2 -> 1.3 --- Log message: new testcase for isascii --- Diffs of the changes: (+4 -2) IsDigit.ll | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/test/Regression/Transforms/SimplifyLibCalls/IsDigit.ll diff -u llvm/test/Regression/Transforms/SimplifyLibCalls/IsDigit.ll:1.2 llvm/test/Regression/Transforms/SimplifyLibCalls/IsDigit.ll:1.3 --- llvm/test/Regression/Transforms/SimplifyLibCalls/IsDigit.ll:1.2 Wed May 4 12:45:10 2005 +++ llvm/test/Regression/Transforms/SimplifyLibCalls/IsDigit.ll Thu Sep 29 01:16:37 2005 @@ -1,7 +1,8 @@ ; Test that the IsDigitOptimizer works correctly -; RUN: llvm-as < %s | opt -simplify-libcalls | llvm-dis | not grep 'call.*isdigit' +; RUN: llvm-as < %s | opt -simplify-libcalls | llvm-dis | not grep 'call' declare int %isdigit(int) +declare int %isascii(int) implementation ; Functions: @@ -14,5 +15,6 @@ %rslt2 = add int %val3, %val4 %sum = add int %rslt1, %rslt2 %rslt = call int %isdigit(int %sum) - ret int %rslt + %tmp = call int %isascii(int %rslt) + ret int %tmp } From lattner at cs.uiuc.edu Thu Sep 29 01:17:39 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 01:17:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Message-ID: <200509290617.BAA01027@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: SimplifyLibCalls.cpp updated: 1.53 -> 1.54 --- Log message: Fold isascii into a simple comparison. This speeds up 197.parser by 7.4%, bringing the LLC time down to the CBE time. --- Diffs of the changes: (+26 -0) SimplifyLibCalls.cpp | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+) Index: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp diff -u llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.53 llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.54 --- llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.53 Thu Sep 29 01:16:11 2005 +++ llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Thu Sep 29 01:17:27 2005 @@ -1745,6 +1745,32 @@ } } isdigitOptimizer; +struct isasciiOptimization : public LibCallOptimization { +public: + isasciiOptimization() + : LibCallOptimization("isascii", "Number of 'isascii' calls simplified") {} + + virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){ + return F->arg_size() == 1 && F->arg_begin()->getType()->isInteger() && + F->getReturnType()->isInteger(); + } + + /// @brief Perform the isascii optimization. + virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) { + // isascii(c) -> (unsigned)c < 128 + Value *V = CI->getOperand(1); + if (V->getType()->isSigned()) + V = new CastInst(V, V->getType()->getUnsignedVersion(), V->getName(), CI); + Value *Cmp = BinaryOperator::createSetLT(V, ConstantUInt::get(V->getType(), + 128), + V->getName()+".isascii", CI); + if (Cmp->getType() != CI->getType()) + Cmp = new CastInst(Cmp, CI->getType(), Cmp->getName(), CI); + CI->replaceAllUsesWith(Cmp); + CI->eraseFromParent(); + return true; + } +} isasciiOptimizer; /// This LibCallOptimization will simplify calls to the "toascii" library From lattner at cs.uiuc.edu Thu Sep 29 01:44:51 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 01:44:51 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200509290644.BAA01208@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.187 -> 1.188 --- Log message: Fix two bugs in my patch earlier today that broke int->fp conversion on X86. --- Diffs of the changes: (+2 -2) LegalizeDAG.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.187 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.188 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.187 Wed Sep 28 17:28:18 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Sep 29 01:44:39 2005 @@ -261,7 +261,7 @@ } NeedsAnotherIteration = true; - return DAG.getNode(ISD::ADD, DestVT, Tmp1, FudgeInReg); + return DAG.getNode(ISD::FADD, DestVT, Tmp1, FudgeInReg); } /// PromoteLegalINT_TO_FP - This function is responsible for legalizing a @@ -2810,7 +2810,7 @@ FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), CPIdx, DAG.getSrcValue(NULL), MVT::f32); } - return DAG.getNode(ISD::ADD, DestTy, SignedConv, FudgeInReg); + return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg); } // Check to see if the target has a custom way to lower this. If so, use it. From lattner at cs.uiuc.edu Thu Sep 29 12:31:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 12:31:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp Message-ID: <200509291731.MAA06808@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCTargetMachine.cpp updated: 1.68 -> 1.69 --- Log message: Make the JIT default to the DAG isel instead of the pattern isel, like LLC. The Pattern isel has some strange memory corruption issues going on. :( This should have been converted over anyway, but it got forgotten somehow when switching to the dag isel. --- Diffs of the changes: (+4 -1) PowerPCTargetMachine.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.68 llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.69 --- llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.68 Mon Sep 26 19:14:41 2005 +++ llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp Thu Sep 29 12:31:03 2005 @@ -145,7 +145,10 @@ PM.add(createUnreachableBlockEliminationPass()); // Install an instruction selector. - PM.add(createPPC32ISelPattern(TM)); + if (!DisablePPCDAGDAG) + PM.add(createPPC32ISelDag(TM)); + else + PM.add(createPPC32ISelPattern(TM)); PM.add(createRegisterAllocator()); PM.add(createPrologEpilogCodeInserter()); From lattner at cs.uiuc.edu Thu Sep 29 12:39:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 12:39:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200509291739.MAA06872@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.179 -> 1.180 --- Log message: consistency with other cases, no functionality change --- Diffs of the changes: (+2 -0) PPC32ISelPattern.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.179 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.180 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.179 Wed Sep 28 17:29:58 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Thu Sep 29 12:38:52 2005 @@ -1058,6 +1058,8 @@ DestType = N.getValue(0).getValueType(); if (Result == 1) Result = ExprMap[N.getValue(0)] = MakeReg(DestType); + else + ExprMap[N.getValue(1)] = 1; Tmp1 = dyn_cast(Node->getOperand(1))->getReg(); if (MVT::isInteger(DestType)) BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp1).addReg(Tmp1); From lattner at cs.uiuc.edu Thu Sep 29 12:44:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 12:44:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LowerInvoke.cpp Message-ID: <200509291744.MAA06980@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LowerInvoke.cpp updated: 1.31 -> 1.32 --- Log message: Insert stores after phi nodes in the normal dest. This fixes LowerInvoke/2005-08-03-InvokeWithPHI.ll --- Diffs of the changes: (+5 -2) LowerInvoke.cpp | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Scalar/LowerInvoke.cpp diff -u llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.31 llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.32 --- llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.31 Tue Sep 27 17:44:59 2005 +++ llvm/lib/Transforms/Scalar/LowerInvoke.cpp Thu Sep 29 12:44:20 2005 @@ -259,8 +259,11 @@ // Insert a store of the invoke num before the invoke and store zero into the // location afterward. new StoreInst(InvokeNoC, InvokeNum, true, II); // volatile - new StoreInst(Constant::getNullValue(Type::UIntTy), InvokeNum, false, - II->getNormalDest()->begin()); // nonvolatile. + + BasicBlock::iterator NI = II->getNormalDest()->begin(); + while (isa(NI)) ++NI; + // nonvolatile. + new StoreInst(Constant::getNullValue(Type::UIntTy), InvokeNum, false, NI); // Add a switch case to our unwind block. CatchSwitch->addCase(InvokeNoC, II->getUnwindDest()); From lattner at cs.uiuc.edu Thu Sep 29 14:28:22 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 14:28:22 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200509291928.OAA08373@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.49 -> 1.50 DAGISelEmitter.h updated: 1.28 -> 1.29 --- Log message: Teach tblgen to build permutations of instructions, so that the target author doesn't have to specify them manually. It currently handles associativity, e.g. knowing that (X*Y)+Z also matches X+(Y*Z) and will be extended in the future. It is smart enough to not introduce duplicate patterns or patterns that can never match. --- Diffs of the changes: (+193 -6) DAGISelEmitter.cpp | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++-- DAGISelEmitter.h | 6 + 2 files changed, 193 insertions(+), 6 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.49 llvm/utils/TableGen/DAGISelEmitter.cpp:1.50 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.49 Wed Sep 28 15:58:06 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Sep 29 14:28:10 2005 @@ -232,6 +232,32 @@ print(std::cerr); } +/// isIsomorphicTo - Return true if this node is recursively isomorphic to +/// the specified node. For this comparison, all of the state of the node +/// is considered, except for the assigned name. Nodes with differing names +/// that are otherwise identical are considered isomorphic. +bool TreePatternNode::isIsomorphicTo(const TreePatternNode *N) const { + if (N == this) return true; + if (N->isLeaf() != isLeaf() || getType() != N->getType() || + getPredicateFn() != N->getPredicateFn() || + getTransformFn() != N->getTransformFn()) + return false; + + if (isLeaf()) { + if (DefInit *DI = dynamic_cast(getLeafValue())) + if (DefInit *NDI = dynamic_cast(N->getLeafValue())) + return DI->getDef() == NDI->getDef(); + return getLeafValue() == N->getLeafValue(); + } + + if (N->getOperator() != getOperator() || + N->getNumChildren() != getNumChildren()) return false; + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) + if (!getChild(i)->isIsomorphicTo(N->getChild(i))) + return false; + return true; +} + /// clone - Make a copy of this tree and all of its children. /// TreePatternNode *TreePatternNode::clone() const { @@ -1042,18 +1068,165 @@ PatternsToMatch.push_back(std::make_pair(Pattern->getOnlyTree(), Result->getOnlyTree())); } +} - DEBUG(std::cerr << "\n\nPARSED PATTERNS TO MATCH:\n\n"; - for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) { - std::cerr << "PATTERN: "; PatternsToMatch[i].first->dump(); - std::cerr << "\nRESULT: ";PatternsToMatch[i].second->dump(); - std::cerr << "\n"; - }); +/// CombineChildVariants - Given a bunch of permutations of each child of the +/// 'operator' node, put them together in all possible ways. +static void CombineChildVariants(TreePatternNode *Orig, + std::vector > &ChildVariants, + std::vector &OutVariants, + DAGISelEmitter &ISE) { + // The end result is an all-pairs construction of the resultant pattern. + std::vector Idxs; + Idxs.resize(ChildVariants.size()); + bool NotDone = true; + while (NotDone) { + // Create the variant and add it to the output list. + std::vector NewChildren; + for (unsigned i = 0, e = ChildVariants.size(); i != e; ++i) + NewChildren.push_back(ChildVariants[i][Idxs[i]]); + TreePatternNode *R = new TreePatternNode(Orig->getOperator(), NewChildren); + + // Copy over properties. + R->setName(Orig->getName()); + R->setPredicateFn(Orig->getPredicateFn()); + R->setTransformFn(Orig->getTransformFn()); + R->setType(Orig->getType()); + + // If this pattern cannot every match, do not include it as a variant. + std::string ErrString; + if (!R->canPatternMatch(ErrString, ISE)) { + delete R; + } else { + bool AlreadyExists = false; + + // Scan to see if this pattern has already been emitted. We can get + // duplication due to things like commuting: + // (and GPRC:$a, GPRC:$b) -> (and GPRC:$b, GPRC:$a) + // which are the same pattern. Ignore the dups. + for (unsigned i = 0, e = OutVariants.size(); i != e; ++i) + if (R->isIsomorphicTo(OutVariants[i])) { + AlreadyExists = true; + break; + } + + if (AlreadyExists) + delete R; + else + OutVariants.push_back(R); + } + + // Increment indices to the next permutation. + NotDone = false; + // Look for something we can increment without causing a wrap-around. + for (unsigned IdxsIdx = 0; IdxsIdx != Idxs.size(); ++IdxsIdx) { + if (++Idxs[IdxsIdx] < ChildVariants[IdxsIdx].size()) { + NotDone = true; // Found something to increment. + break; + } + Idxs[IdxsIdx] = 0; + } + } } +/// GenerateVariantsOf - Given a pattern N, generate all permutations we can of +/// the (potentially recursive) pattern by using algebraic laws. +/// +static void GenerateVariantsOf(TreePatternNode *N, + std::vector &OutVariants, + DAGISelEmitter &ISE) { + // We cannot permute leaves. + if (N->isLeaf()) { + OutVariants.push_back(N); + return; + } + + // Look up interesting info about the node. + const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(N->getOperator()); + + // If this node is associative, reassociate. + // TODO! + + // Compute permutations of all children. + std::vector > ChildVariants; + ChildVariants.resize(N->getNumChildren()); + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) + GenerateVariantsOf(N->getChild(i), ChildVariants[i], ISE); + + // Build all permutations based on how the children were formed. + CombineChildVariants(N, ChildVariants, OutVariants, ISE); + + // If this node is commutative, consider the commuted order. + if (NodeInfo.hasProperty(SDNodeInfo::SDNPCommutative)) { + assert(N->getNumChildren()==2 &&"Commutative but doesn't have 2 children!"); + std::vector > CommChildVariants; + CommChildVariants.push_back(ChildVariants[1]); + CommChildVariants.push_back(ChildVariants[0]); + + // Consider all commuted orders. + CombineChildVariants(N, CommChildVariants, OutVariants, ISE); + } +} + + // GenerateVariants - Generate variants. For example, commutative patterns can // match multiple ways. Add them to PatternsToMatch as well. void DAGISelEmitter::GenerateVariants() { + + DEBUG(std::cerr << "Generating instruction variants.\n"); + + // Loop over all of the patterns we've collected, checking to see if we can + // generate variants of the instruction, through the exploitation of + // identities. This permits the target to provide agressive matching without + // the .td file having to contain tons of variants of instructions. + // + // Note that this loop adds new patterns to the PatternsToMatch list, but we + // intentionally do not reconsider these. Any variants of added patterns have + // already been added. + // + for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) { + std::vector Variants; + GenerateVariantsOf(PatternsToMatch[i].first, Variants, *this); + + assert(!Variants.empty() && "Must create at least original variant!"); + assert(Variants[0]->isIsomorphicTo(PatternsToMatch[i].first) && + "Input pattern should be first variant!"); + Variants.erase(Variants.begin()); // Remove the original pattern. + + if (Variants.empty()) // No variants for this pattern. + continue; + + DEBUG(std::cerr << "FOUND VARIANTS OF: "; + PatternsToMatch[i].first->dump(); + std::cerr << "\n"); + + for (unsigned v = 0, e = Variants.size(); v != e; ++v) { + TreePatternNode *Variant = Variants[v]; + + DEBUG(std::cerr << " VAR#" << v << ": "; + Variant->dump(); + std::cerr << "\n"); + + // Scan to see if an instruction or explicit pattern already matches this. + bool AlreadyExists = false; + for (unsigned p = 0, e = PatternsToMatch.size(); p != e; ++p) { + // Check to see if this variant already exists. + if (Variant->isIsomorphicTo(PatternsToMatch[p].first)) { + DEBUG(std::cerr << " *** ALREADY EXISTS, ignoring variant.\n"); + AlreadyExists = true; + break; + } + } + // If we already have it, ignore the variant. + if (AlreadyExists) continue; + + // Otherwise, add it to the list of patterns we have. + PatternsToMatch.push_back(std::make_pair(Variant, + PatternsToMatch[i].second)); + } + + DEBUG(std::cerr << "\n"); + } } @@ -1381,6 +1554,14 @@ // multiple ways. Add them to PatternsToMatch as well. GenerateVariants(); + + DEBUG(std::cerr << "\n\nALL PATTERNS TO MATCH:\n\n"; + for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) { + std::cerr << "PATTERN: "; PatternsToMatch[i].first->dump(); + std::cerr << "\nRESULT: ";PatternsToMatch[i].second->dump(); + std::cerr << "\n"; + }); + // At this point, we have full information about the 'Patterns' we need to // parse, both implicitly from instructions as well as from explicit pattern // definitions. Emit the resultant instruction selector. Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.28 llvm/utils/TableGen/DAGISelEmitter.h:1.29 --- llvm/utils/TableGen/DAGISelEmitter.h:1.28 Wed Sep 28 15:58:06 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Thu Sep 29 14:28:10 2005 @@ -174,6 +174,12 @@ /// TreePatternNode *clone() const; + /// isIsomorphicTo - Return true if this node is recursively isomorphic to + /// the specified node. For this comparison, all of the state of the node + /// is considered, except for the assigned name. Nodes with differing names + /// that are otherwise identical are considered isomorphic. + bool isIsomorphicTo(const TreePatternNode *N) const; + /// SubstituteFormalArguments - Replace the formal arguments in this tree /// with actual values specified by ArgMap. void SubstituteFormalArguments(std::map Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.111 -> 1.112 --- Log message: now that tblgen is smarter, this pattern is not needed. Also, tblgen now inverts commuted versions of ANDC/ORC with the current .td file. --- Diffs of the changes: (+1 -3) PowerPCInstrInfo.td | 4 +--- 1 files changed, 1 insertion(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.111 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.112 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.111 Wed Sep 28 18:07:13 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Thu Sep 29 14:29:15 2005 @@ -802,11 +802,9 @@ (NOR GPRC:$in, GPRC:$in)>; // EQV patterns +// FIXME: This should be autogenerated from the above due to xor association. def EQV1 : Pat<(xor (not GPRC:$in1), GPRC:$in2), (EQV GPRC:$in1, GPRC:$in2)>; -// FIXME: This should be autogenerated from the above due to xor commutativity. -def EQV2 : Pat<(xor GPRC:$in1, (not GPRC:$in2)), - (EQV GPRC:$in1, GPRC:$in2)>; // ADD an arbitrary immediate. def : Pat<(add GPRC:$in, imm:$imm), From alenhar2 at cs.uiuc.edu Thu Sep 29 16:12:09 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 29 Sep 2005 16:12:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCSubtarget.h Message-ID: <200509292112.QAA09321@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCSubtarget.h updated: 1.5 -> 1.6 --- Log message: copy and paste error --- Diffs of the changes: (+1 -1) PowerPCSubtarget.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PowerPCSubtarget.h diff -u llvm/lib/Target/PowerPC/PowerPCSubtarget.h:1.5 llvm/lib/Target/PowerPC/PowerPCSubtarget.h:1.6 --- llvm/lib/Target/PowerPC/PowerPCSubtarget.h:1.5 Tue Sep 6 10:30:12 2005 +++ llvm/lib/Target/PowerPC/PowerPCSubtarget.h Thu Sep 29 16:11:57 2005 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file declares the X86 specific subclass of TargetSubtarget. +// This file declares the PowerPC specific subclass of TargetSubtarget. // //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Thu Sep 29 17:37:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 17:37:05 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200509292237.RAA12124@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.50 -> 1.51 --- Log message: Teach tablegen to reassociate operators when possible. This allows it to find all of teh pattern matches for EQV from one definition --- Diffs of the changes: (+96 -10) DAGISelEmitter.cpp | 106 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 96 insertions(+), 10 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.50 llvm/utils/TableGen/DAGISelEmitter.cpp:1.51 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.50 Thu Sep 29 14:28:10 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Sep 29 17:36:54 2005 @@ -1073,9 +1073,14 @@ /// CombineChildVariants - Given a bunch of permutations of each child of the /// 'operator' node, put them together in all possible ways. static void CombineChildVariants(TreePatternNode *Orig, - std::vector > &ChildVariants, + const std::vector > &ChildVariants, std::vector &OutVariants, DAGISelEmitter &ISE) { + // Make sure that each operand has at least one variant to choose from. + for (unsigned i = 0, e = ChildVariants.size(); i != e; ++i) + if (ChildVariants[i].empty()) + return; + // The end result is an all-pairs construction of the resultant pattern. std::vector Idxs; Idxs.resize(ChildVariants.size()); @@ -1129,6 +1134,43 @@ } } +/// CombineChildVariants - A helper function for binary operators. +/// +static void CombineChildVariants(TreePatternNode *Orig, + const std::vector &LHS, + const std::vector &RHS, + std::vector &OutVariants, + DAGISelEmitter &ISE) { + std::vector > ChildVariants; + ChildVariants.push_back(LHS); + ChildVariants.push_back(RHS); + CombineChildVariants(Orig, ChildVariants, OutVariants, ISE); +} + + +static void GatherChildrenOfAssociativeOpcode(TreePatternNode *N, + std::vector &Children) { + assert(N->getNumChildren()==2 &&"Associative but doesn't have 2 children!"); + Record *Operator = N->getOperator(); + + // Only permit raw nodes. + if (!N->getName().empty() || !N->getPredicateFn().empty() || + N->getTransformFn()) { + Children.push_back(N); + return; + } + + if (N->getChild(0)->isLeaf() || N->getChild(0)->getOperator() != Operator) + Children.push_back(N->getChild(0)); + else + GatherChildrenOfAssociativeOpcode(N->getChild(0), Children); + + if (N->getChild(1)->isLeaf() || N->getChild(1)->getOperator() != Operator) + Children.push_back(N->getChild(1)); + else + GatherChildrenOfAssociativeOpcode(N->getChild(1), Children); +} + /// GenerateVariantsOf - Given a pattern N, generate all permutations we can of /// the (potentially recursive) pattern by using algebraic laws. /// @@ -1145,7 +1187,56 @@ const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(N->getOperator()); // If this node is associative, reassociate. - // TODO! + if (NodeInfo.hasProperty(SDNodeInfo::SDNPAssociative)) { + // Reassociate by pulling together all of the linked operators + std::vector MaximalChildren; + GatherChildrenOfAssociativeOpcode(N, MaximalChildren); + + // Only handle child sizes of 3. Otherwise we'll end up trying too many + // permutations. + if (MaximalChildren.size() == 3) { + // Find the variants of all of our maximal children. + std::vector AVariants, BVariants, CVariants; + GenerateVariantsOf(MaximalChildren[0], AVariants, ISE); + GenerateVariantsOf(MaximalChildren[1], BVariants, ISE); + GenerateVariantsOf(MaximalChildren[2], CVariants, ISE); + + // There are only two ways we can permute the tree: + // (A op B) op C and A op (B op C) + // Within these forms, we can also permute A/B/C. + + // Generate legal pair permutations of A/B/C. + std::vector ABVariants; + std::vector BAVariants; + std::vector ACVariants; + std::vector CAVariants; + std::vector BCVariants; + std::vector CBVariants; + CombineChildVariants(N, AVariants, BVariants, ABVariants, ISE); + CombineChildVariants(N, BVariants, AVariants, BAVariants, ISE); + CombineChildVariants(N, AVariants, CVariants, ACVariants, ISE); + CombineChildVariants(N, CVariants, AVariants, CAVariants, ISE); + CombineChildVariants(N, BVariants, CVariants, BCVariants, ISE); + CombineChildVariants(N, CVariants, BVariants, CBVariants, ISE); + + // Combine those into the result: (x op x) op x + CombineChildVariants(N, ABVariants, CVariants, OutVariants, ISE); + CombineChildVariants(N, BAVariants, CVariants, OutVariants, ISE); + CombineChildVariants(N, ACVariants, BVariants, OutVariants, ISE); + CombineChildVariants(N, CAVariants, BVariants, OutVariants, ISE); + CombineChildVariants(N, BCVariants, AVariants, OutVariants, ISE); + CombineChildVariants(N, CBVariants, AVariants, OutVariants, ISE); + + // Combine those into the result: x op (x op x) + CombineChildVariants(N, CVariants, ABVariants, OutVariants, ISE); + CombineChildVariants(N, CVariants, BAVariants, OutVariants, ISE); + CombineChildVariants(N, BVariants, ACVariants, OutVariants, ISE); + CombineChildVariants(N, BVariants, CAVariants, OutVariants, ISE); + CombineChildVariants(N, AVariants, BCVariants, OutVariants, ISE); + CombineChildVariants(N, AVariants, CBVariants, OutVariants, ISE); + return; + } + } // Compute permutations of all children. std::vector > ChildVariants; @@ -1159,12 +1250,9 @@ // If this node is commutative, consider the commuted order. if (NodeInfo.hasProperty(SDNodeInfo::SDNPCommutative)) { assert(N->getNumChildren()==2 &&"Commutative but doesn't have 2 children!"); - std::vector > CommChildVariants; - CommChildVariants.push_back(ChildVariants[1]); - CommChildVariants.push_back(ChildVariants[0]); - - // Consider all commuted orders. - CombineChildVariants(N, CommChildVariants, OutVariants, ISE); + // Consider the commuted order. + CombineChildVariants(N, ChildVariants[1], ChildVariants[0], + OutVariants, ISE); } } @@ -1189,8 +1277,6 @@ GenerateVariantsOf(PatternsToMatch[i].first, Variants, *this); assert(!Variants.empty() && "Must create at least original variant!"); - assert(Variants[0]->isIsomorphicTo(PatternsToMatch[i].first) && - "Input pattern should be first variant!"); Variants.erase(Variants.begin()); // Remove the original pattern. if (Variants.empty()) // No variants for this pattern. From lattner at cs.uiuc.edu Thu Sep 29 17:37:36 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 17:37:36 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509292237.RAA12181@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.112 -> 1.113 --- Log message: tblgen autogens this pattern now --- Diffs of the changes: (+0 -6) PowerPCInstrInfo.td | 6 ------ 1 files changed, 6 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.112 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.113 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.112 Thu Sep 29 14:29:15 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Thu Sep 29 17:37:24 2005 @@ -796,16 +796,10 @@ def : Pat<(i32 imm:$imm), (ORI (LIS (HI16 imm:$imm)), (LO16 imm:$imm))>; - // Implement the 'not' operation with the NOR instruction. def NOT : Pat<(not GPRC:$in), (NOR GPRC:$in, GPRC:$in)>; -// EQV patterns -// FIXME: This should be autogenerated from the above due to xor association. -def EQV1 : Pat<(xor (not GPRC:$in1), GPRC:$in2), - (EQV GPRC:$in1, GPRC:$in2)>; - // ADD an arbitrary immediate. def : Pat<(add GPRC:$in, imm:$imm), (ADDIS (ADDI GPRC:$in, (LO16 imm:$imm)), (HA16 imm:$imm))>; From alenhar2 at cs.uiuc.edu Thu Sep 29 17:55:07 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 29 Sep 2005 17:55:07 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaSubtarget.cpp AlphaSubtarget.h AlphaAsmPrinter.cpp AlphaISelLowering.cpp AlphaISelPattern.cpp AlphaTargetMachine.cpp AlphaTargetMachine.h Message-ID: <200509292255.RAA12299@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaSubtarget.cpp added (r1.1) AlphaSubtarget.h added (r1.1) AlphaAsmPrinter.cpp updated: 1.19 -> 1.20 AlphaISelLowering.cpp updated: 1.5 -> 1.6 AlphaISelPattern.cpp updated: 1.171 -> 1.172 AlphaTargetMachine.cpp updated: 1.12 -> 1.13 AlphaTargetMachine.h updated: 1.9 -> 1.10 --- Log message: begining alpha subtarget support --- Diffs of the changes: (+86 -19) AlphaAsmPrinter.cpp | 9 +++------ AlphaISelLowering.cpp | 4 +--- AlphaISelPattern.cpp | 11 +++-------- AlphaSubtarget.cpp | 28 ++++++++++++++++++++++++++++ AlphaSubtarget.h | 42 ++++++++++++++++++++++++++++++++++++++++++ AlphaTargetMachine.cpp | 8 ++++++-- AlphaTargetMachine.h | 3 +++ 7 files changed, 86 insertions(+), 19 deletions(-) Index: llvm/lib/Target/Alpha/AlphaSubtarget.cpp diff -c /dev/null llvm/lib/Target/Alpha/AlphaSubtarget.cpp:1.1 *** /dev/null Thu Sep 29 17:55:06 2005 --- llvm/lib/Target/Alpha/AlphaSubtarget.cpp Thu Sep 29 17:54:56 2005 *************** *** 0 **** --- 1,28 ---- + //===- AlphaSubtarget.cpp - Alpha Subtarget Information ---------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Andrew Lenharth and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file implements the Alpha specific subclass of TargetSubtarget. + // + //===----------------------------------------------------------------------===// + + #include "AlphaSubtarget.h" + #include "Alpha.h" + #include "llvm/Module.h" + #include "llvm/Support/CommandLine.h" + #include "llvm/Target/SubtargetFeature.h" + + using namespace llvm; + + //"alphaev67-unknown-linux-gnu" + + AlphaSubtarget::AlphaSubtarget(const Module &M, const std::string &FS) + :HasF2I(false), HasCT(false) + { + //TODO: figure out host + } Index: llvm/lib/Target/Alpha/AlphaSubtarget.h diff -c /dev/null llvm/lib/Target/Alpha/AlphaSubtarget.h:1.1 *** /dev/null Thu Sep 29 17:55:07 2005 --- llvm/lib/Target/Alpha/AlphaSubtarget.h Thu Sep 29 17:54:56 2005 *************** *** 0 **** --- 1,42 ---- + //=====-- AlphaSubtarget.h - Define Subtarget for the Alpha --*- C++ -*--====// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Andrew Lenharth and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file declares the Alpha specific subclass of TargetSubtarget. + // + //===----------------------------------------------------------------------===// + + #ifndef ALPHASUBTARGET_H + #define ALPHASUBTARGET_H + + #include "llvm/Target/TargetSubtarget.h" + + #include + + namespace llvm { + class Module; + + class AlphaSubtarget : public TargetSubtarget { + protected: + + /// Used by the ISel to turn in optimizations for POWER4-derived architectures + bool HasF2I; + bool HasCT; + + public: + /// This constructor initializes the data members to match that + /// of the specified module. + /// + AlphaSubtarget(const Module &M, const std::string &FS); + + bool hasF2I() const { return HasF2I; } + bool hasCT() const { return HasCT; } + }; + } // End llvm namespace + + #endif Index: llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp diff -u llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.19 llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.20 --- llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.19 Fri Aug 12 11:13:43 2005 +++ llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp Thu Sep 29 17:54:56 2005 @@ -14,6 +14,7 @@ #include "Alpha.h" #include "AlphaInstrInfo.h" +#include "AlphaTargetMachine.h" #include "llvm/Module.h" #include "llvm/Type.h" #include "llvm/Assembly/Writer.h" @@ -29,11 +30,6 @@ using namespace llvm; -namespace llvm { - extern cl::opt EnableAlphaFTOI; - extern cl::opt EnableAlphaCT; -} - namespace { Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); @@ -235,7 +231,8 @@ bool AlphaAsmPrinter::doInitialization(Module &M) { AsmPrinter::doInitialization(M); - if(EnableAlphaFTOI || EnableAlphaCT) + if(TM.getSubtarget().hasF2I() + || TM.getSubtarget().hasCT()) O << "\t.arch ev6\n"; else O << "\t.arch ev56\n"; Index: llvm/lib/Target/Alpha/AlphaISelLowering.cpp diff -u llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.5 llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.6 --- llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.5 Wed Sep 28 17:29:17 2005 +++ llvm/lib/Target/Alpha/AlphaISelLowering.cpp Thu Sep 29 17:54:56 2005 @@ -27,8 +27,6 @@ namespace llvm { extern cl::opt EnableAlphaIDIV; - extern cl::opt EnableAlphaFTOI; - extern cl::opt EnableAlphaCT; extern cl::opt EnableAlphaCount; extern cl::opt EnableAlphaLSMark; } @@ -73,7 +71,7 @@ setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); - if (!EnableAlphaCT) { + if (!TM.getSubtarget().hasCT()) { setOperationAction(ISD::CTPOP , MVT::i64 , Expand); setOperationAction(ISD::CTTZ , MVT::i64 , Expand); setOperationAction(ISD::CTLZ , MVT::i64 , Expand); Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.171 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.172 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.171 Wed Sep 28 17:29:17 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Thu Sep 29 17:54:56 2005 @@ -13,6 +13,7 @@ #include "Alpha.h" #include "AlphaRegisterInfo.h" +#include "AlphaTargetMachine.h" #include "AlphaISelLowering.h" #include "llvm/Constants.h" // FIXME: REMOVE #include "llvm/Function.h" @@ -38,12 +39,6 @@ cl::opt EnableAlphaIDIV("enable-alpha-intfpdiv", cl::desc("Use the FP div instruction for integer div when possible"), cl::Hidden); - cl::opt EnableAlphaFTOI("enable-alpha-FTOI", - cl::desc("Enable use of ftoi* and itof* instructions (ev6 and higher)"), - cl::Hidden); - cl::opt EnableAlphaCT("enable-alpha-CT", - cl::desc("Enable use of the ctpop, ctlz, and cttz instructions"), - cl::Hidden); cl::opt EnableAlphaCount("enable-alpha-count", cl::desc("Print estimates on live ins and outs"), cl::Hidden); @@ -428,7 +423,7 @@ void AlphaISel::MoveFP2Int(unsigned src, unsigned dst, bool isDouble) { unsigned Opc; - if (EnableAlphaFTOI) { + if (TLI.getTargetMachine().getSubtarget().hasF2I()) { Opc = isDouble ? Alpha::FTOIT : Alpha::FTOIS; BuildMI(BB, Opc, 1, dst).addReg(src).addReg(Alpha::F31); } else { @@ -455,7 +450,7 @@ void AlphaISel::MoveInt2FP(unsigned src, unsigned dst, bool isDouble) { unsigned Opc; - if (EnableAlphaFTOI) { + if (TLI.getTargetMachine().getSubtarget().hasF2I()) { Opc = isDouble?Alpha::ITOFT:Alpha::ITOFS; BuildMI(BB, Opc, 1, dst).addReg(src).addReg(Alpha::R31); } else { Index: llvm/lib/Target/Alpha/AlphaTargetMachine.cpp diff -u llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.12 llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.13 --- llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.12 Thu Sep 1 16:38:20 2005 +++ llvm/lib/Target/Alpha/AlphaTargetMachine.cpp Thu Sep 29 17:54:56 2005 @@ -18,6 +18,7 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetMachineRegistry.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Support/Debug.h" #include using namespace llvm; @@ -62,8 +63,11 @@ const std::string &FS) : TargetMachine("alpha", IL, true), FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0), - JITInfo(*this) -{} + JITInfo(*this), + Subtarget(M, FS) +{ + DEBUG(std::cerr << "FS is " << FS << "\n"); +} /// addPassesToEmitFile - Add passes to the specified pass manager to implement /// a static compiler for this target. Index: llvm/lib/Target/Alpha/AlphaTargetMachine.h diff -u llvm/lib/Target/Alpha/AlphaTargetMachine.h:1.9 llvm/lib/Target/Alpha/AlphaTargetMachine.h:1.10 --- llvm/lib/Target/Alpha/AlphaTargetMachine.h:1.9 Thu Sep 1 16:38:20 2005 +++ llvm/lib/Target/Alpha/AlphaTargetMachine.h Thu Sep 29 17:54:56 2005 @@ -19,6 +19,7 @@ #include "llvm/PassManager.h" #include "AlphaInstrInfo.h" #include "AlphaJITInfo.h" +#include "AlphaSubtarget.h" namespace llvm { @@ -29,6 +30,7 @@ AlphaInstrInfo InstrInfo; TargetFrameInfo FrameInfo; AlphaJITInfo JITInfo; + AlphaSubtarget Subtarget; public: AlphaTargetMachine(const Module &M, IntrinsicLowering *IL, @@ -36,6 +38,7 @@ virtual const AlphaInstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } + virtual const TargetSubtarget *getSubtargetImpl() const{ return &Subtarget; } virtual const MRegisterInfo *getRegisterInfo() const { return &InstrInfo.getRegisterInfo(); } From lattner at cs.uiuc.edu Thu Sep 29 18:33:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 18:33:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509292333.SAA12531@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.86 -> 1.87 --- Log message: Remove code for patterns that are autogenerated --- Diffs of the changes: (+9 -30) PPC32ISelDAGToDAG.cpp | 39 +++++++++------------------------------ 1 files changed, 9 insertions(+), 30 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.86 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.87 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.86 Wed Sep 28 19:59:32 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Thu Sep 29 18:33:31 2005 @@ -847,9 +847,8 @@ } } - CurDAG->SelectNodeTo(N, PPC::DIVW, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); + // Other cases are autogenerated. + break; } case ISD::UDIV: { // If this is a divide by constant, we can emit code using some magic @@ -861,9 +860,8 @@ return Result; } - CurDAG->SelectNodeTo(N, PPC::DIVWU, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); + // Other cases are autogenerated. + break; } case ISD::AND: { unsigned Imm; @@ -884,18 +882,9 @@ getI32Imm(MB), getI32Imm(ME)); return SDOperand(N, 0); } - // Finally, check for the case where we are being asked to select - // and (not(a), b) or and (a, not(b)) which can be selected as andc. - if (isOprNot(N->getOperand(0).Val)) - CurDAG->SelectNodeTo(N, PPC::ANDC, MVT::i32, Select(N->getOperand(1)), - Select(N->getOperand(0).getOperand(0))); - else if (isOprNot(N->getOperand(1).Val)) - CurDAG->SelectNodeTo(N, PPC::ANDC, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1).getOperand(0))); - else - CurDAG->SelectNodeTo(N, PPC::AND, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); + + // Other cases are autogenerated. + break; } case ISD::OR: if (SDNode *I = SelectBitfieldInsert(N)) @@ -906,18 +895,8 @@ PPC::ORIS, PPC::ORI)) return CodeGenMap[Op] = SDOperand(I, 0); - // Finally, check for the case where we are being asked to select - // 'or (not(a), b)' or 'or (a, not(b))' which can be selected as orc. - if (isOprNot(N->getOperand(0).Val)) - CurDAG->SelectNodeTo(N, PPC::ORC, MVT::i32, Select(N->getOperand(1)), - Select(N->getOperand(0).getOperand(0))); - else if (isOprNot(N->getOperand(1).Val)) - CurDAG->SelectNodeTo(N, PPC::ORC, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1).getOperand(0))); - else - CurDAG->SelectNodeTo(N, PPC::OR, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); + // Other cases are autogenerated. + break; case ISD::SHL: { unsigned Imm, SH, MB, ME; if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) && From lattner at cs.uiuc.edu Thu Sep 29 18:34:36 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 18:34:36 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td PowerPCInstrFormats.td Message-ID: <200509292334.SAA12566@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.113 -> 1.114 PowerPCInstrFormats.td updated: 1.50 -> 1.51 --- Log message: Add a bunch of patterns for F64 FP ops, add some more integer ops --- Diffs of the changes: (+84 -38) PowerPCInstrFormats.td | 19 +++++---- PowerPCInstrInfo.td | 103 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 84 insertions(+), 38 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.113 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.114 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.113 Thu Sep 29 17:37:24 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Thu Sep 29 18:34:24 2005 @@ -76,6 +76,9 @@ def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz SDTCisSameAs<0, 1>, SDTCisInt<0> ]>; +def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc + SDTCisSameAs<0, 1>, SDTCisFP<0> +]>; def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>, SDTCisVTSmallerThanOp<2, 1> @@ -117,6 +120,9 @@ def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; def srem : SDNode<"ISD::SREM" , SDTIntBinOp>; def urem : SDNode<"ISD::UREM" , SDTIntBinOp>; +def srl : SDNode<"ISD::SRL" , SDTIntBinOp>; +def sra : SDNode<"ISD::SRA" , SDTIntBinOp>; +def shl : SDNode<"ISD::SHL" , SDTIntBinOp>; def and : SDNode<"ISD::AND" , SDTIntBinOp, [SDNPCommutative, SDNPAssociative]>; def or : SDNode<"ISD::OR" , SDTIntBinOp, @@ -128,6 +134,9 @@ def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>; def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; +def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; +def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; +def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; @@ -533,19 +542,19 @@ []>, isPPC64; def SLW : XForm_6<31, 24, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "slw $rA, $rS, $rB", - []>; + [(set GPRC:$rA, (shl GPRC:$rS, GPRC:$rB))]>; def SRD : XForm_6<31, 539, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "srd $rA, $rS, $rB", []>, isPPC64; def SRW : XForm_6<31, 536, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "srw $rA, $rS, $rB", - []>; + [(set GPRC:$rA, (srl GPRC:$rS, GPRC:$rB))]>; def SRAD : XForm_6<31, 794, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "srad $rA, $rS, $rB", []>, isPPC64; def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "sraw $rA, $rS, $rB", - []>; + [(set GPRC:$rA, (sra GPRC:$rS, GPRC:$rB))]>; let isStore = 1 in { def STBX : XForm_8<31, 215, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), "stbx $rS, $rA, $rB">; @@ -561,7 +570,8 @@ "stdux $rS, $rA, $rB">, isPPC64; } def SRAWI : XForm_10<31, 824, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH), - "srawi $rA, $rS, $SH">; + "srawi $rA, $rS, $SH", + [(set GPRC:$rA, (sra GPRC:$rS, imm:$SH))]>; def CNTLZW : XForm_11<31, 26, (ops GPRC:$rA, GPRC:$rS), "cntlzw $rA, $rS", [(set GPRC:$rA, (ctlz GPRC:$rS))]>; @@ -597,25 +607,35 @@ "lfdx $dst, $base, $index">; } def FCFID : XForm_26<63, 846, (ops FPRC:$frD, FPRC:$frB), - "fcfid $frD, $frB">, isPPC64; + "fcfid $frD, $frB", + []>, isPPC64; def FCTIDZ : XForm_26<63, 815, (ops FPRC:$frD, FPRC:$frB), - "fctidz $frD, $frB">, isPPC64; + "fctidz $frD, $frB", + []>, isPPC64; def FCTIWZ : XForm_26<63, 15, (ops FPRC:$frD, FPRC:$frB), - "fctiwz $frD, $frB">; + "fctiwz $frD, $frB", + []>; def FABS : XForm_26<63, 264, (ops FPRC:$frD, FPRC:$frB), - "fabs $frD, $frB">; + "fabs $frD, $frB", + [(set FPRC:$frD, (fabs FPRC:$frB))]>; def FMR : XForm_26<63, 72, (ops FPRC:$frD, FPRC:$frB), - "fmr $frD, $frB">; + "fmr $frD, $frB", + []>; // (set FPRC:$frD, FPRC:$frB) def FNABS : XForm_26<63, 136, (ops FPRC:$frD, FPRC:$frB), - "fnabs $frD, $frB">; + "fnabs $frD, $frB", + [(set FPRC:$frD, (fneg (fabs FPRC:$frB)))]>; def FNEG : XForm_26<63, 40, (ops FPRC:$frD, FPRC:$frB), - "fneg $frD, $frB">; + "fneg $frD, $frB", + [(set FPRC:$frD, (fneg FPRC:$frB))]>; def FRSP : XForm_26<63, 12, (ops FPRC:$frD, FPRC:$frB), - "frsp $frD, $frB">; + "frsp $frD, $frB", + []>; def FSQRT : XForm_26<63, 22, (ops FPRC:$frD, FPRC:$frB), - "fsqrt $frD, $frB">; + "fsqrt $frD, $frB", + [(set FPRC:$frD, (fsqrt FPRC:$frB))]>; def FSQRTS : XForm_26<59, 22, (ops FPRC:$frD, FPRC:$frB), - "fsqrts $frD, $frB">; + "fsqrts $frD, $frB", + []>; let isStore = 1 in { def STFSX : XForm_28<31, 663, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB), @@ -711,55 +731,76 @@ // def FMADD : AForm_1<63, 29, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), - "fmadd $FRT, $FRA, $FRC, $FRB">; + "fmadd $FRT, $FRA, $FRC, $FRB", + [(set FPRC:$FRT, (fadd (fmul FPRC:$FRA, FPRC:$FRC), + FPRC:$FRB))]>; def FMADDS : AForm_1<59, 29, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), - "fmadds $FRT, $FRA, $FRC, $FRB">; + "fmadds $FRT, $FRA, $FRC, $FRB", + []>; def FMSUB : AForm_1<63, 28, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), - "fmsub $FRT, $FRA, $FRC, $FRB">; + "fmsub $FRT, $FRA, $FRC, $FRB", + [(set FPRC:$FRT, (fsub (fmul FPRC:$FRA, FPRC:$FRC), + FPRC:$FRB))]>; def FMSUBS : AForm_1<59, 28, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), - "fmsubs $FRT, $FRA, $FRC, $FRB">; + "fmsubs $FRT, $FRA, $FRC, $FRB", + []>; def FNMADD : AForm_1<63, 31, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), - "fnmadd $FRT, $FRA, $FRC, $FRB">; + "fnmadd $FRT, $FRA, $FRC, $FRB", + [(set FPRC:$FRT, (fneg (fadd (fmul FPRC:$FRA, FPRC:$FRC), + FPRC:$FRB)))]>; def FNMADDS : AForm_1<59, 31, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), - "fnmadds $FRT, $FRA, $FRC, $FRB">; + "fnmadds $FRT, $FRA, $FRC, $FRB", + []>; def FNMSUB : AForm_1<63, 30, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), - "fnmsub $FRT, $FRA, $FRC, $FRB">; + "fnmsub $FRT, $FRA, $FRC, $FRB", + [(set FPRC:$FRT, (fneg (fsub (fmul FPRC:$FRA, FPRC:$FRC), + FPRC:$FRB)))]>; def FNMSUBS : AForm_1<59, 30, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), - "fnmsubs $FRT, $FRA, $FRC, $FRB">; + "fnmsubs $FRT, $FRA, $FRC, $FRB", + []>; def FSEL : AForm_1<63, 23, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), - "fsel $FRT, $FRA, $FRC, $FRB">; + "fsel $FRT, $FRA, $FRC, $FRB", + []>; def FADD : AForm_2<63, 21, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), - "fadd $FRT, $FRA, $FRB">; + "fadd $FRT, $FRA, $FRB", + [(set FPRC:$FRT, (fadd FPRC:$FRA, FPRC:$FRB))]>; def FADDS : AForm_2<59, 21, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), - "fadds $FRT, $FRA, $FRB">; + "fadds $FRT, $FRA, $FRB", + []>; def FDIV : AForm_2<63, 18, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), - "fdiv $FRT, $FRA, $FRB">; + "fdiv $FRT, $FRA, $FRB", + [(set FPRC:$FRT, (fdiv FPRC:$FRA, FPRC:$FRB))]>; def FDIVS : AForm_2<59, 18, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), - "fdivs $FRT, $FRA, $FRB">; + "fdivs $FRT, $FRA, $FRB", + []>; def FMUL : AForm_3<63, 25, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), - "fmul $FRT, $FRA, $FRB">; + "fmul $FRT, $FRA, $FRB", + [(set FPRC:$FRT, (fmul FPRC:$FRA, FPRC:$FRB))]>; def FMULS : AForm_3<59, 25, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), - "fmuls $FRT, $FRA, $FRB">; + "fmuls $FRT, $FRA, $FRB", + []>; def FSUB : AForm_2<63, 20, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), - "fsub $FRT, $FRA, $FRB">; + "fsub $FRT, $FRA, $FRB", + [(set FPRC:$FRT, (fsub FPRC:$FRA, FPRC:$FRB))]>; def FSUBS : AForm_2<59, 20, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), - "fsubs $FRT, $FRA, $FRB">; + "fsubs $FRT, $FRA, $FRB", + []>; // M-Form instructions. rotate and mask instructions. // Index: llvm/lib/Target/PowerPC/PowerPCInstrFormats.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.50 llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.51 --- llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.50 Thu Sep 8 12:40:49 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrFormats.td Thu Sep 29 18:34:24 2005 @@ -240,8 +240,9 @@ class XForm_8 opcode, bits<10> xo, dag OL, string asmstr> : XForm_base_r3xo; -class XForm_10 opcode, bits<10> xo, dag OL, string asmstr> +class XForm_10 opcode, bits<10> xo, dag OL, string asmstr, list pt> : XForm_base_r3xo_swapped { + let Pattern = pt; } class XForm_11 opcode, bits<10> xo, dag OL, string asmstr, @@ -290,9 +291,10 @@ : XForm_base_r3xo { } -class XForm_26 opcode, bits<10> xo, dag OL, string asmstr> +class XForm_26 opcode, bits<10> xo, dag OL, string asmstr, list pt> : XForm_base_r3xo { let A = 0; + let Pattern = pt; } class XForm_28 opcode, bits<10> xo, dag OL, string asmstr> @@ -463,13 +465,16 @@ } // 1.7.12 A-Form -class AForm_1 opcode, bits<5> xo, dag OL, string asmstr> +class AForm_1 opcode, bits<5> xo, dag OL, string asmstr, + list pattern> : I { bits<5> FRT; bits<5> FRA; bits<5> FRC; bits<5> FRB; + let Pattern = pattern; + bit RC = 0; // set by isDOT let Inst{6-10} = FRT; @@ -480,13 +485,13 @@ let Inst{31} = RC; } -class AForm_2 opcode, bits<5> xo, dag OL, string asmstr> - : AForm_1 { +class AForm_2 opcode, bits<5> xo, dag OL, string asmstr, list pat> + : AForm_1 { let FRC = 0; } -class AForm_3 opcode, bits<5> xo, dag OL, string asmstr> - : AForm_1 { +class AForm_3 opcode, bits<5> xo, dag OL, string asmstr, list pat> + : AForm_1 { let FRB = 0; } From lattner at cs.uiuc.edu Thu Sep 29 19:05:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 19:05:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPC.td Message-ID: <200509300005.TAA12744@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPC.td updated: 1.12 -> 1.13 --- Log message: Use the 32-bit version for now --- Diffs of the changes: (+1 -1) PowerPC.td | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PowerPC.td diff -u llvm/lib/Target/PowerPC/PowerPC.td:1.12 llvm/lib/Target/PowerPC/PowerPC.td:1.13 --- llvm/lib/Target/PowerPC/PowerPC.td:1.12 Thu Dec 16 10:31:57 2004 +++ llvm/lib/Target/PowerPC/PowerPC.td Thu Sep 29 19:05:05 2005 @@ -18,7 +18,7 @@ // Register File Description //===----------------------------------------------------------------------===// -include "PPC64RegisterInfo.td" +include "PPC32RegisterInfo.td" include "PowerPCInstrInfo.td" def PowerPC : Target { From lattner at cs.uiuc.edu Thu Sep 29 20:28:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 20:28:25 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200509300128.UAA13371@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.58 -> 1.59 --- Log message: Change these methods to take RC's --- Diffs of the changes: (+4 -2) MRegisterInfo.h | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.58 llvm/include/llvm/Target/MRegisterInfo.h:1.59 --- llvm/include/llvm/Target/MRegisterInfo.h:1.58 Fri Sep 16 20:02:45 2005 +++ llvm/include/llvm/Target/MRegisterInfo.h Thu Sep 29 20:28:14 2005 @@ -239,11 +239,13 @@ virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIndex) const = 0; + unsigned SrcReg, int FrameIndex, + const TargetRegisterClass *RC) const = 0; virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIndex) const = 0; + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC) const = 0; virtual void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, From lattner at cs.uiuc.edu Thu Sep 29 20:29:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 20:29:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PrologEpilogInserter.cpp RegAllocLocal.cpp RegAllocSimple.cpp VirtRegMap.cpp Message-ID: <200509300129.UAA13434@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: PrologEpilogInserter.cpp updated: 1.46 -> 1.47 RegAllocLocal.cpp updated: 1.73 -> 1.74 RegAllocSimple.cpp updated: 1.64 -> 1.65 VirtRegMap.cpp updated: 1.39 -> 1.40 --- Log message: Change this code ot pass register classes into the stack slot spiller/reloader code. PrologEpilogInserter hasn't been updated yet though, so targets cannot use this info. --- Diffs of the changes: (+19 -11) PrologEpilogInserter.cpp | 6 ++++-- RegAllocLocal.cpp | 4 ++-- RegAllocSimple.cpp | 4 ++-- VirtRegMap.cpp | 16 +++++++++++----- 4 files changed, 19 insertions(+), 11 deletions(-) Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.46 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.47 --- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.46 Sun Aug 28 19:10:46 2005 +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp Thu Sep 29 20:29:00 2005 @@ -200,7 +200,8 @@ MachineBasicBlock::iterator I = MBB->begin(); for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { // Insert the spill to the stack frame. - RegInfo->storeRegToStackSlot(*MBB, I, RegsToSave[i], StackSlots[i]); + RegInfo->storeRegToStackSlot(*MBB, I, RegsToSave[i], StackSlots[i], + 0 /*FIXME*/); } // Add code to restore the callee-save registers in each exiting block. @@ -225,7 +226,8 @@ // Restore all registers immediately before the return and any terminators // that preceed it. for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { - RegInfo->loadRegFromStackSlot(*MBB, I, RegsToSave[i], StackSlots[i]); + RegInfo->loadRegFromStackSlot(*MBB, I, RegsToSave[i], StackSlots[i], + 0 /*FIXME*/); assert(I != MBB->begin() && "loadRegFromStackSlot didn't insert any code!"); // Insert in reverse order. loadRegFromStackSlot can insert multiple Index: llvm/lib/CodeGen/RegAllocLocal.cpp diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.73 llvm/lib/CodeGen/RegAllocLocal.cpp:1.74 --- llvm/lib/CodeGen/RegAllocLocal.cpp:1.73 Tue Aug 23 18:42:17 2005 +++ llvm/lib/CodeGen/RegAllocLocal.cpp Thu Sep 29 20:29:00 2005 @@ -270,7 +270,7 @@ const TargetRegisterClass *RC = MF->getSSARegMap()->getRegClass(VirtReg); int FrameIndex = getStackSpaceFor(VirtReg, RC); DEBUG(std::cerr << " to stack slot #" << FrameIndex); - RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIndex); + RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIndex, RC); ++NumStores; // Update statistics } @@ -476,7 +476,7 @@ << RegInfo->getName(PhysReg) << "\n"); // Add move instruction(s) - RegInfo->loadRegFromStackSlot(MBB, MI, PhysReg, FrameIndex); + RegInfo->loadRegFromStackSlot(MBB, MI, PhysReg, FrameIndex, RC); ++NumLoads; // Update statistics PhysRegsEverUsed[PhysReg] = true; Index: llvm/lib/CodeGen/RegAllocSimple.cpp diff -u llvm/lib/CodeGen/RegAllocSimple.cpp:1.64 llvm/lib/CodeGen/RegAllocSimple.cpp:1.65 --- llvm/lib/CodeGen/RegAllocSimple.cpp:1.64 Thu Apr 21 23:01:15 2005 +++ llvm/lib/CodeGen/RegAllocSimple.cpp Thu Sep 29 20:29:00 2005 @@ -135,7 +135,7 @@ // Add move instruction(s) ++NumLoads; - RegInfo->loadRegFromStackSlot(MBB, I, PhysReg, FrameIdx); + RegInfo->loadRegFromStackSlot(MBB, I, PhysReg, FrameIdx, RC); return PhysReg; } @@ -147,7 +147,7 @@ // Add move instruction(s) ++NumStores; - RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIdx); + RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIdx, RC); } Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.39 llvm/lib/CodeGen/VirtRegMap.cpp:1.40 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.39 Mon Sep 19 01:56:21 2005 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Sep 29 20:29:00 2005 @@ -163,18 +163,20 @@ unsigned PhysReg = VRM.getPhys(VirtReg); if (VRM.hasStackSlot(VirtReg)) { int StackSlot = VRM.getStackSlot(VirtReg); + const TargetRegisterClass* RC = + MF.getSSARegMap()->getRegClass(VirtReg); if (MO.isUse() && std::find(LoadedRegs.begin(), LoadedRegs.end(), VirtReg) == LoadedRegs.end()) { - MRI.loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot); + MRI.loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot, RC); LoadedRegs.push_back(VirtReg); ++NumLoads; DEBUG(std::cerr << '\t' << *prior(MII)); } if (MO.isDef()) { - MRI.storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot); + MRI.storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC); ++NumStores; } } @@ -386,6 +388,8 @@ // Otherwise, reload it and remember that we have it. PhysReg = VRM.getPhys(VirtReg); + const TargetRegisterClass* RC = + MBB.getParent()->getSSARegMap()->getRegClass(VirtReg); RecheckRegister: // Note that, if we reused a register for a previous operand, the @@ -406,7 +410,7 @@ // was used. This isn't good because it means we have // to undo a previous reuse. MRI->loadRegFromStackSlot(MBB, &MI, Op.AssignedPhysReg, - Op.StackSlot); + Op.StackSlot, RC); ClobberPhysReg(Op.AssignedPhysReg, SpillSlotsAvailable, PhysRegsAvailable); @@ -431,7 +435,7 @@ } ContinueReload: PhysRegsUsed[PhysReg] = true; - MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot); + MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot, RC); // This invalidates PhysReg. ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable); @@ -553,6 +557,8 @@ if (!TakenCareOf) { // The only vregs left are stack slot definitions. int StackSlot = VRM.getStackSlot(VirtReg); + const TargetRegisterClass *RC = + MBB.getParent()->getSSARegMap()->getRegClass(VirtReg); unsigned PhysReg; // If this is a def&use operand, and we used a different physreg for @@ -564,7 +570,7 @@ PhysReg = MO.getReg(); PhysRegsUsed[PhysReg] = true; - MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot); + MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC); DEBUG(std::cerr << "Store:\t" << *next(MII)); MI.SetMachineOperandReg(i, PhysReg); From lattner at cs.uiuc.edu Thu Sep 29 20:29:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 20:29:55 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Skeleton/SkeletonRegisterInfo.cpp SkeletonRegisterInfo.h Message-ID: <200509300129.UAA13513@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Skeleton: SkeletonRegisterInfo.cpp updated: 1.6 -> 1.7 SkeletonRegisterInfo.h updated: 1.7 -> 1.8 --- Log message: Pass extra regclasses into spilling code --- Diffs of the changes: (+9 -5) SkeletonRegisterInfo.cpp | 6 ++++-- SkeletonRegisterInfo.h | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) Index: llvm/lib/Target/Skeleton/SkeletonRegisterInfo.cpp diff -u llvm/lib/Target/Skeleton/SkeletonRegisterInfo.cpp:1.6 llvm/lib/Target/Skeleton/SkeletonRegisterInfo.cpp:1.7 --- llvm/lib/Target/Skeleton/SkeletonRegisterInfo.cpp:1.6 Fri Aug 19 13:35:41 2005 +++ llvm/lib/Target/Skeleton/SkeletonRegisterInfo.cpp Thu Sep 29 20:29:42 2005 @@ -22,13 +22,15 @@ void SkeletonRegisterInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIdx) const { + unsigned SrcReg, int FrameIdx, + const TargetRegisterClass *RC) const { abort(); } void SkeletonRegisterInfo:: loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned DestReg, int FrameIdx) const { + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *RC) const { abort(); } Index: llvm/lib/Target/Skeleton/SkeletonRegisterInfo.h diff -u llvm/lib/Target/Skeleton/SkeletonRegisterInfo.h:1.7 llvm/lib/Target/Skeleton/SkeletonRegisterInfo.h:1.8 --- llvm/lib/Target/Skeleton/SkeletonRegisterInfo.h:1.7 Fri Aug 19 13:35:41 2005 +++ llvm/lib/Target/Skeleton/SkeletonRegisterInfo.h Thu Sep 29 20:29:42 2005 @@ -1,4 +1,4 @@ -//===- SkeletonRegisterInfo.h - Skeleton Register Information Impl -*- C++ -*-==// +//===- SkeletonRegisterInfo.h - Skeleton Register Info Impl ------*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -24,11 +24,13 @@ void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex) const; + unsigned SrcReg, int FrameIndex, + const TargetRegisterClass *RC) const; void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned DestReg, int FrameIndex) const; + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC) const; void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, From lattner at cs.uiuc.edu Thu Sep 29 20:29:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 20:29:55 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp AlphaRegisterInfo.h Message-ID: <200509300129.UAA13519@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaRegisterInfo.cpp updated: 1.26 -> 1.27 AlphaRegisterInfo.h updated: 1.5 -> 1.6 --- Log message: Pass extra regclasses into spilling code --- Diffs of the changes: (+8 -4) AlphaRegisterInfo.cpp | 6 ++++-- AlphaRegisterInfo.h | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) Index: llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp diff -u llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.26 llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.27 --- llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.26 Fri Aug 19 13:33:26 2005 +++ llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp Thu Sep 29 20:29:42 2005 @@ -75,7 +75,8 @@ void AlphaRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx) const { + unsigned SrcReg, int FrameIdx, + const TargetRegisterClass *RC) const { //std::cerr << "Trying to store " << getPrettyName(SrcReg) << " to " << FrameIdx << "\n"; //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg); if (EnableAlphaLSMark) @@ -92,7 +93,8 @@ void AlphaRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIdx) const{ + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *RC) const { //std::cerr << "Trying to load " << getPrettyName(DestReg) << " to " << FrameIdx << "\n"; if (EnableAlphaLSMark) BuildMI(MBB, MI, Alpha::MEMLABEL, 4).addImm(4).addImm(0).addImm(2) Index: llvm/lib/Target/Alpha/AlphaRegisterInfo.h diff -u llvm/lib/Target/Alpha/AlphaRegisterInfo.h:1.5 llvm/lib/Target/Alpha/AlphaRegisterInfo.h:1.6 --- llvm/lib/Target/Alpha/AlphaRegisterInfo.h:1.5 Fri Aug 19 13:33:26 2005 +++ llvm/lib/Target/Alpha/AlphaRegisterInfo.h Thu Sep 29 20:29:42 2005 @@ -27,11 +27,13 @@ /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex) const; + unsigned SrcReg, int FrameIndex, + const TargetRegisterClass *RC) const; void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned DestReg, int FrameIndex) const; + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC) const; void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, From lattner at cs.uiuc.edu Thu Sep 29 20:29:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 20:29:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp SparcV8RegisterInfo.h Message-ID: <200509300129.UAA13537@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8RegisterInfo.cpp updated: 1.26 -> 1.27 SparcV8RegisterInfo.h updated: 1.5 -> 1.6 --- Log message: Pass extra regclasses into spilling code --- Diffs of the changes: (+8 -4) SparcV8RegisterInfo.cpp | 6 ++++-- SparcV8RegisterInfo.h | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp diff -u llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.26 llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.27 --- llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.26 Fri Aug 19 13:50:11 2005 +++ llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp Thu Sep 29 20:29:42 2005 @@ -40,7 +40,8 @@ void SparcV8RegisterInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned SrcReg, int FrameIdx) const { + unsigned SrcReg, int FrameIdx, + const TargetRegisterClass *rc) const { const TargetRegisterClass *RC = getClass(SrcReg); // On the order of operands here: think "[FrameIdx + 0] = SrcReg". @@ -59,7 +60,8 @@ void SparcV8RegisterInfo:: loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned DestReg, int FrameIdx) const { + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *rc) const { const TargetRegisterClass *RC = getClass(DestReg); if (RC == V8::IntRegsRegisterClass) BuildMI (MBB, I, V8::LD, 2, DestReg).addFrameIndex (FrameIdx).addSImm (0); Index: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h diff -u llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h:1.5 llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h:1.6 --- llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h:1.5 Thu Apr 21 18:21:30 2005 +++ llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h Thu Sep 29 20:29:42 2005 @@ -28,11 +28,13 @@ /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex) const; + unsigned SrcReg, int FrameIndex, + const TargetRegisterClass *RC) const; void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned DestReg, int FrameIndex) const; + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC) const; void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, From lattner at cs.uiuc.edu Thu Sep 29 20:29:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 20:29:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp SparcV9RegisterInfo.h Message-ID: <200509300129.UAA13529@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9RegisterInfo.cpp updated: 1.5 -> 1.6 SparcV9RegisterInfo.h updated: 1.7 -> 1.8 --- Log message: Pass extra regclasses into spilling code --- Diffs of the changes: (+8 -4) SparcV9RegisterInfo.cpp | 6 ++++-- SparcV9RegisterInfo.h | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) Index: llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp diff -u llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp:1.5 llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp:1.6 --- llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp:1.5 Thu Apr 21 18:25:42 2005 +++ llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp Thu Sep 29 20:29:42 2005 @@ -278,13 +278,15 @@ void SparcV9RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIndex) const{ + unsigned SrcReg, int FrameIndex, + const TargetRegisterClass *RC) const { abort (); } void SparcV9RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIndex) const { + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC) const { abort (); } Index: llvm/lib/Target/SparcV9/SparcV9RegisterInfo.h diff -u llvm/lib/Target/SparcV9/SparcV9RegisterInfo.h:1.7 llvm/lib/Target/SparcV9/SparcV9RegisterInfo.h:1.8 --- llvm/lib/Target/SparcV9/SparcV9RegisterInfo.h:1.7 Thu Apr 21 18:25:42 2005 +++ llvm/lib/Target/SparcV9/SparcV9RegisterInfo.h Thu Sep 29 20:29:42 2005 @@ -27,10 +27,12 @@ // The rest of these are stubs... for now. void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIndex) const; + unsigned SrcReg, int FrameIndex, + const TargetRegisterClass *RC) const; void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIndex) const; + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC) const; void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, From lattner at cs.uiuc.edu Thu Sep 29 20:29:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 20:29:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp X86RegisterInfo.h Message-ID: <200509300129.UAA13527@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.109 -> 1.110 X86RegisterInfo.h updated: 1.31 -> 1.32 --- Log message: Pass extra regclasses into spilling code --- Diffs of the changes: (+8 -4) X86RegisterInfo.cpp | 6 ++++-- X86RegisterInfo.h | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.109 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.110 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.109 Mon Sep 19 00:23:44 2005 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Thu Sep 29 20:29:42 2005 @@ -58,7 +58,8 @@ void X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx) const { + unsigned SrcReg, int FrameIdx, + const TargetRegisterClass *RC) const { static const unsigned Opcode[] = { X86::MOV8mr, X86::MOV16mr, X86::MOV32mr, X86::FST64m, X86::FSTP80m, X86::MOVAPDmr }; @@ -70,7 +71,8 @@ void X86RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIdx)const{ + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *RC) const{ static const unsigned Opcode[] = { X86::MOV8rm, X86::MOV16rm, X86::MOV32rm, X86::FLD64m, X86::FLD80m, X86::MOVAPDrm }; Index: llvm/lib/Target/X86/X86RegisterInfo.h diff -u llvm/lib/Target/X86/X86RegisterInfo.h:1.31 llvm/lib/Target/X86/X86RegisterInfo.h:1.32 --- llvm/lib/Target/X86/X86RegisterInfo.h:1.31 Mon Sep 19 00:23:44 2005 +++ llvm/lib/Target/X86/X86RegisterInfo.h Thu Sep 29 20:29:42 2005 @@ -28,11 +28,13 @@ /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIndex) const; + unsigned SrcReg, int FrameIndex, + const TargetRegisterClass *RC) const; void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIndex) const; + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC) const; void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, From lattner at cs.uiuc.edu Thu Sep 29 20:30:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 20:30:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64RegisterInfo.cpp IA64RegisterInfo.h Message-ID: <200509300130.UAA13604@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64RegisterInfo.cpp updated: 1.6 -> 1.7 IA64RegisterInfo.h updated: 1.3 -> 1.4 --- Log message: these methods get extra args --- Diffs of the changes: (+10 -6) IA64RegisterInfo.cpp | 10 ++++++---- IA64RegisterInfo.h | 6 ++++-- 2 files changed, 10 insertions(+), 6 deletions(-) Index: llvm/lib/Target/IA64/IA64RegisterInfo.cpp diff -u llvm/lib/Target/IA64/IA64RegisterInfo.cpp:1.6 llvm/lib/Target/IA64/IA64RegisterInfo.cpp:1.7 --- llvm/lib/Target/IA64/IA64RegisterInfo.cpp:1.6 Fri Aug 19 13:34:37 2005 +++ llvm/lib/Target/IA64/IA64RegisterInfo.cpp Thu Sep 29 20:30:29 2005 @@ -49,8 +49,9 @@ } void IA64RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx) const { + MachineBasicBlock::iterator MI, + unsigned SrcReg, int FrameIdx, + const TargetRegisterClass *RC) const{ if (getClass(SrcReg) == IA64::FPRegisterClass) { BuildMI(MBB, MI, IA64::STF8, 2).addFrameIndex(FrameIdx).addReg(SrcReg); @@ -72,8 +73,9 @@ } void IA64RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIdx)const{ + MachineBasicBlock::iterator MI, + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *RC)const{ if (getClass(DestReg) == IA64::FPRegisterClass) { BuildMI(MBB, MI, IA64::LDF8, 1, DestReg).addFrameIndex(FrameIdx); Index: llvm/lib/Target/IA64/IA64RegisterInfo.h diff -u llvm/lib/Target/IA64/IA64RegisterInfo.h:1.3 llvm/lib/Target/IA64/IA64RegisterInfo.h:1.4 --- llvm/lib/Target/IA64/IA64RegisterInfo.h:1.3 Fri Aug 19 13:34:37 2005 +++ llvm/lib/Target/IA64/IA64RegisterInfo.h Thu Sep 29 20:30:29 2005 @@ -27,11 +27,13 @@ /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIndex) const; + unsigned SrcReg, int FrameIndex, + const TargetRegisterClass *RC) const; void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIndex) const; + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC) const; void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, From lattner at cs.uiuc.edu Thu Sep 29 20:31:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 20:31:07 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32RegisterInfo.h Message-ID: <200509300131.UAA13662@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32RegisterInfo.h updated: 1.5 -> 1.6 --- Log message: these methods get extra args --- Diffs of the changes: (+4 -2) PPC32RegisterInfo.h | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.h diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.h:1.5 llvm/lib/Target/PowerPC/PPC32RegisterInfo.h:1.6 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.h:1.5 Fri Sep 16 20:03:26 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.h Thu Sep 29 20:30:55 2005 @@ -30,11 +30,13 @@ /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex) const; + unsigned SrcReg, int FrameIndex, + const TargetRegisterClass *RC) const; void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned DestReg, int FrameIndex) const; + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC) const; void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, From lattner at cs.uiuc.edu Thu Sep 29 20:32:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 20:32:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Message-ID: <200509300132.UAA13743@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32RegisterInfo.cpp updated: 1.24 -> 1.25 --- Log message: pass extra args --- Diffs of the changes: (+4 -2) PPC32RegisterInfo.cpp | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.24 llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.25 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.24 Fri Sep 16 20:03:26 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Thu Sep 29 20:31:52 2005 @@ -79,7 +79,8 @@ void PPC32RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx) const { + unsigned SrcReg, int FrameIdx, + const TargetRegisterClass *RC) const { static const unsigned Opcode[] = { PPC::STB, PPC::STH, PPC::STW, PPC::STFS, PPC::STFD }; @@ -99,7 +100,8 @@ void PPC32RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIdx) const { + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *RC) const { static const unsigned Opcode[] = { PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LFS, PPC::LFD }; From lattner at cs.uiuc.edu Thu Sep 29 20:34:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 20:34:00 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200509300134.UAA13807@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.30 -> 1.31 --- Log message: allow regs to be in multiple reg classes --- Diffs of the changes: (+2 -18) RegisterInfoEmitter.cpp | 20 ++------------------ 1 files changed, 2 insertions(+), 18 deletions(-) Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.30 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.31 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.30 Fri Aug 19 15:23:42 2005 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Thu Sep 29 20:33:48 2005 @@ -101,8 +101,6 @@ const std::vector &RegisterClasses = Target.getRegisterClasses(); - std::set RegistersFound; - // Loop over all of the register classes... emitting each one. OS << "namespace { // Register classes...\n"; @@ -121,10 +119,6 @@ << "[] = {\n "; for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) { Record *Reg = RC.Elements[i]; - if (RegistersFound.count(Reg)) - throw "Register '" + Reg->getName() + - "' included in multiple register classes!"; - RegistersFound.insert(Reg); OS << getQualifiedName(Reg) << ", "; // Keep track of which regclasses this register is in. @@ -232,18 +226,8 @@ unsigned SpillAlign = Reg.DeclaredSpillAlignment; for (; I != E; ++I) { // For each reg class this belongs to. const CodeGenRegisterClass *RC = I->second; - if (SpillSize == 0) - SpillSize = RC->SpillSize; - else if (SpillSize != RC->SpillSize) - throw "Spill size for regclass '" + RC->getName() + - "' doesn't match spill sized already inferred for register '" + - Reg.getName() + "'!"; - if (SpillAlign == 0) - SpillAlign = RC->SpillAlignment; - else if (SpillAlign != RC->SpillAlignment) - throw "Spill alignment for regclass '" + RC->getName() + - "' doesn't match spill sized already inferred for register '" + - Reg.getName() + "'!"; + SpillSize = std::max(SpillSize, RC->SpillSize); + SpillAlign = std::max(SpillAlign, RC->SpillAlignment); } OS << SpillSize << ", " << SpillAlign << " },\n"; From lattner at cs.uiuc.edu Thu Sep 29 23:10:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 23:10:28 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/TableGen/ForwardRef.td Message-ID: <200509300410.XAA15272@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/TableGen: ForwardRef.td added (r1.1) --- Log message: Check that we can refer to the same class we are defining. --- Diffs of the changes: (+6 -0) ForwardRef.td | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/test/Regression/TableGen/ForwardRef.td diff -c /dev/null llvm/test/Regression/TableGen/ForwardRef.td:1.1 *** /dev/null Thu Sep 29 23:10:27 2005 --- llvm/test/Regression/TableGen/ForwardRef.td Thu Sep 29 23:10:17 2005 *************** *** 0 **** --- 1,6 ---- + // RUN: tblgen %s -o - + + class bar { + list x; + } + From lattner at cs.uiuc.edu Thu Sep 29 23:11:01 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 23:11:01 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.y Message-ID: <200509300411.XAA15306@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.y updated: 1.36 -> 1.37 --- Log message: Refactor the grammar a bit to implement TableGen/ForwardRef.td --- Diffs of the changes: (+38 -28) FileParser.y | 66 +++++++++++++++++++++++++++++++++-------------------------- 1 files changed, 38 insertions(+), 28 deletions(-) Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.36 llvm/utils/TableGen/FileParser.y:1.37 --- llvm/utils/TableGen/FileParser.y:1.36 Mon Sep 12 00:29:43 2005 +++ llvm/utils/TableGen/FileParser.y Thu Sep 29 23:10:49 2005 @@ -533,21 +533,40 @@ OptID : ID { $$ = $1; } | /*empty*/ { $$ = new std::string(); }; -ObjectBody : OptID { - static unsigned AnonCounter = 0; - if ($1->empty()) - *$1 = "anonymous."+utostr(AnonCounter++); - CurRec = new Record(*$1); - delete $1; - ParsingTemplateArgs = true; - } OptTemplateArgList ClassList { +ObjectName : OptID { + static unsigned AnonCounter = 0; + if ($1->empty()) + *$1 = "anonymous."+utostr(AnonCounter++); + CurRec = new Record(*$1); + delete $1; + ParsingTemplateArgs = true; +}; + +ClassName : ObjectName { + if (Records.getClass(CurRec->getName())) { + err() << "Class '" << CurRec->getName() << "' already defined!\n"; + exit(1); + } + Records.addClass(CurRec); +}; + +DefName : ObjectName { + // Ensure redefinition doesn't happen. + if (Records.getDef(CurRec->getName())) { + err() << "Def '" << CurRec->getName() << "' already defined!\n"; + exit(1); + } + Records.addDef(CurRec); +}; + +ObjectBody : OptTemplateArgList ClassList { ParsingTemplateArgs = false; - for (unsigned i = 0, e = $4->size(); i != e; ++i) { - addSubClass((*$4)[i].first, *(*$4)[i].second); + for (unsigned i = 0, e = $2->size(); i != e; ++i) { + addSubClass((*$2)[i].first, *(*$2)[i].second); // Delete the template arg values for the class - delete (*$4)[i].second; + delete (*$2)[i].second; } - delete $4; // Delete the class list... + delete $2; // Delete the class list... // Process any variables on the set stack... for (unsigned i = 0, e = LetStack.size(); i != e; ++i) @@ -560,29 +579,20 @@ CurRec = 0; }; -ClassInst : CLASS ObjectBody { - if (Records.getClass($2->getName())) { - err() << "Class '" << $2->getName() << "' already defined!\n"; - exit(1); - } - Records.addClass($$ = $2); +ClassInst : CLASS ClassName ObjectBody { + $$ = $3; }; -DefInst : DEF ObjectBody { - $2->resolveReferences(); +DefInst : DEF DefName ObjectBody { + $3->resolveReferences(); // If ObjectBody has template arguments, it's an error. - if (!$2->getTemplateArgs().empty()) { - err() << "Def '" << $2->getName() + if (!$3->getTemplateArgs().empty()) { + err() << "Def '" << $3->getName() << "' is not permitted to have template arguments!\n"; exit(1); } - // Ensure redefinition doesn't happen. - if (Records.getDef($2->getName())) { - err() << "Def '" << $2->getName() << "' already defined!\n"; - exit(1); - } - Records.addDef($$ = $2); + $$ = $3; }; From lattner at cs.uiuc.edu Thu Sep 29 23:11:40 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 23:11:40 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.cpp FileParser.h Message-ID: <200509300411.XAA15388@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.cpp updated: 1.5 -> 1.6 FileParser.h updated: 1.3 -> 1.4 --- Log message: regenerate --- Diffs of the changes: (+1165 -1604) FileParser.cpp | 2658 ++++++++++++++++++++++++--------------------------------- FileParser.h | 111 -- 2 files changed, 1165 insertions(+), 1604 deletions(-) Index: llvm/utils/TableGen/FileParser.cpp diff -u llvm/utils/TableGen/FileParser.cpp:1.5 llvm/utils/TableGen/FileParser.cpp:1.6 --- llvm/utils/TableGen/FileParser.cpp:1.5 Mon Sep 12 00:30:06 2005 +++ llvm/utils/TableGen/FileParser.cpp Thu Sep 29 23:11:27 2005 @@ -1,115 +1,38 @@ -/* A Bison parser, made by GNU Bison 1.875. */ -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. +/* A Bison parser, made from /Users/sabre/llvm/utils/TableGen/FileParser.y + by GNU Bison version 1.28 */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. +#define YYBISON 1 /* Identify Bison output. */ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Written by Richard Stallman by simplifying the original so called - ``semantic'' parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - -/* If NAME_PREFIX is specified substitute the variables and functions - names. */ #define yyparse Fileparse -#define yylex Filelex +#define yylex Filelex #define yyerror Fileerror -#define yylval Filelval -#define yychar Filechar +#define yylval Filelval +#define yychar Filechar #define yydebug Filedebug #define yynerrs Filenerrs +#define INT 257 +#define BIT 258 +#define STRING 259 +#define BITS 260 +#define LIST 261 +#define CODE 262 +#define DAG 263 +#define CLASS 264 +#define DEF 265 +#define FIELD 266 +#define LET 267 +#define IN 268 +#define SHLTOK 269 +#define SRATOK 270 +#define SRLTOK 271 +#define INTVAL 272 +#define ID 273 +#define VARNAME 274 +#define STRVAL 275 +#define CODEFRAGMENT 276 - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - INT = 258, - BIT = 259, - STRING = 260, - BITS = 261, - LIST = 262, - CODE = 263, - DAG = 264, - CLASS = 265, - DEF = 266, - FIELD = 267, - LET = 268, - IN = 269, - SHLTOK = 270, - SRATOK = 271, - SRLTOK = 272, - INTVAL = 273, - ID = 274, - VARNAME = 275, - STRVAL = 276, - CODEFRAGMENT = 277 - }; -#endif -#define INT 258 -#define BIT 259 -#define STRING 260 -#define BITS 261 -#define LIST 262 -#define CODE 263 -#define DAG 264 -#define CLASS 265 -#define DEF 266 -#define FIELD 267 -#define LET 268 -#define IN 269 -#define SHLTOK 270 -#define SRATOK 271 -#define SRLTOK 272 -#define INTVAL 273 -#define ID 274 -#define VARNAME 275 -#define STRVAL 276 -#define CODEFRAGMENT 277 - - - - -/* Copy the first part of user declarations. */ -#line 14 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" +#line 14 "/Users/sabre/llvm/utils/TableGen/FileParser.y" #include "Record.h" #include "llvm/ADT/StringExtras.h" @@ -284,23 +207,8 @@ using namespace llvm; - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 189 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" -typedef union YYSTYPE { +#line 189 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +typedef union { std::string* StrVal; int IntVal; llvm::RecTy* Ty; @@ -312,831 +220,539 @@ std::vector* SubClassList; std::vector >* DagValueList; } YYSTYPE; -/* Line 191 of yacc.c. */ -#line 316 "FileParser.tab.c" -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ - - -/* Line 214 of yacc.c. */ -#line 328 "FileParser.tab.c" - -#if ! defined (yyoverflow) || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# if YYSTACK_USE_ALLOCA -# define YYSTACK_ALLOC alloca -# else -# ifndef YYSTACK_USE_ALLOCA -# if defined (alloca) || defined (_ALLOCA_H) -# define YYSTACK_ALLOC alloca -# else -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -# define YYSTACK_ALLOC malloc -# define YYSTACK_FREE free -# endif -#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - short yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) +#include +#ifndef __cplusplus +#ifndef __STDC__ +#define const #endif - -#if defined (__STDC__) || defined (__cplusplus) - typedef signed char yysigned_char; -#else - typedef short yysigned_char; #endif -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 18 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 153 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 38 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 37 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 85 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 155 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 277 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const unsigned char yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 32, 33, 2, 2, 34, 36, 31, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 35, 37, - 23, 25, 24, 26, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 29, 2, 30, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 27, 2, 28, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22 -}; -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const unsigned short yyprhs[] = -{ - 0, 0, 3, 5, 7, 9, 14, 16, 21, 23, - 25, 27, 28, 30, 31, 34, 36, 38, 40, 42, - 46, 51, 53, 58, 62, 66, 71, 76, 83, 90, - 97, 98, 101, 104, 109, 110, 112, 114, 118, 121, - 125, 131, 136, 138, 139, 143, 144, 146, 148, 152, - 157, 160, 167, 168, 171, 173, 177, 179, 184, 186, - 190, 191, 194, 196, 200, 204, 205, 207, 209, 210, - 211, 212, 219, 222, 225, 227, 229, 234, 236, 240, - 241, 246, 251, 254, 256, 259 + +#define YYFINAL 158 +#define YYFLAG -32768 +#define YYNTBASE 38 + +#define YYTRANSLATE(x) ((unsigned)(x) <= 276 ? yytranslate[x] : 76) + +static const char yytranslate[] = { 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, + 33, 2, 2, 34, 36, 31, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 35, 37, 23, + 25, 24, 26, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 29, 2, 30, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 27, 2, 28, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22 }; -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yysigned_char yyrhs[] = -{ - 74, 0, -1, 19, -1, 5, -1, 4, -1, 6, - 23, 18, 24, -1, 3, -1, 7, 23, 40, 24, - -1, 8, -1, 9, -1, 39, -1, -1, 12, -1, - -1, 25, 43, -1, 18, -1, 21, -1, 22, -1, - 26, -1, 27, 50, 28, -1, 19, 23, 51, 24, - -1, 19, -1, 43, 27, 48, 28, -1, 29, 50, - 30, -1, 43, 31, 19, -1, 32, 19, 46, 33, - -1, 43, 29, 48, 30, -1, 15, 32, 43, 34, - 43, 33, -1, 16, 32, 43, 34, 43, 33, -1, - 17, 32, 43, 34, 43, 33, -1, -1, 35, 20, - -1, 43, 44, -1, 45, 34, 43, 44, -1, -1, - 45, -1, 18, -1, 18, 36, 18, -1, 18, 18, - -1, 47, 34, 18, -1, 47, 34, 18, 36, 18, - -1, 47, 34, 18, 18, -1, 47, -1, -1, 27, - 48, 28, -1, -1, 51, -1, 43, -1, 51, 34, - 43, -1, 41, 40, 19, 42, -1, 52, 37, -1, - 13, 19, 49, 25, 43, 37, -1, -1, 54, 53, - -1, 37, -1, 27, 54, 28, -1, 39, -1, 39, - 23, 51, 24, -1, 56, -1, 57, 34, 56, -1, - -1, 35, 57, -1, 52, -1, 59, 34, 52, -1, - 23, 59, 24, -1, -1, 60, -1, 19, -1, -1, - -1, -1, 62, 64, 61, 58, 65, 55, -1, 10, - 63, -1, 11, 63, -1, 66, -1, 67, -1, 19, - 49, 25, 43, -1, 69, -1, 70, 34, 69, -1, - -1, 13, 72, 70, 14, -1, 71, 27, 73, 28, - -1, 71, 68, -1, 68, -1, 73, 68, -1, 73, - -1 +#if YYDEBUG != 0 +static const short yyprhs[] = { 0, + 0, 2, 4, 6, 11, 13, 18, 20, 22, 24, + 25, 27, 28, 31, 33, 35, 37, 39, 43, 48, + 50, 55, 59, 63, 68, 73, 80, 87, 94, 95, + 98, 101, 106, 107, 109, 111, 115, 118, 122, 128, + 133, 135, 136, 140, 141, 143, 145, 149, 154, 157, + 164, 165, 168, 170, 174, 176, 181, 183, 187, 188, + 191, 193, 197, 201, 202, 204, 206, 207, 209, 211, + 213, 214, 219, 223, 227, 229, 231, 236, 238, 242, + 243, 248, 253, 256, 258, 261 }; -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const unsigned short yyrline[] = -{ - 0, 223, 223, 234, 236, 238, 240, 242, 244, 246, - 248, 252, 252, 254, 254, 256, 258, 261, 264, 266, - 279, 307, 322, 329, 332, 339, 347, 355, 361, 367, - 375, 378, 382, 387, 393, 396, 399, 402, 415, 429, - 431, 444, 460, 462, 462, 466, 468, 472, 475, 479, - 489, 491, 497, 497, 498, 498, 500, 502, 506, 511, - 516, 519, 523, 526, 531, 532, 532, 534, 534, 536, - 543, 536, 563, 571, 589, 589, 591, 596, 596, 599, - 599, 602, 605, 609, 609, 611 +static const short yyrhs[] = { 19, + 0, 5, 0, 4, 0, 6, 23, 18, 24, 0, + 3, 0, 7, 23, 39, 24, 0, 8, 0, 9, + 0, 38, 0, 0, 12, 0, 0, 25, 42, 0, + 18, 0, 21, 0, 22, 0, 26, 0, 27, 49, + 28, 0, 19, 23, 50, 24, 0, 19, 0, 42, + 27, 47, 28, 0, 29, 49, 30, 0, 42, 31, + 19, 0, 32, 19, 45, 33, 0, 42, 29, 47, + 30, 0, 15, 32, 42, 34, 42, 33, 0, 16, + 32, 42, 34, 42, 33, 0, 17, 32, 42, 34, + 42, 33, 0, 0, 35, 20, 0, 42, 43, 0, + 44, 34, 42, 43, 0, 0, 44, 0, 18, 0, + 18, 36, 18, 0, 18, 18, 0, 46, 34, 18, + 0, 46, 34, 18, 36, 18, 0, 46, 34, 18, + 18, 0, 46, 0, 0, 27, 47, 28, 0, 0, + 50, 0, 42, 0, 50, 34, 42, 0, 40, 39, + 19, 41, 0, 51, 37, 0, 13, 19, 48, 25, + 42, 37, 0, 0, 53, 52, 0, 37, 0, 27, + 53, 28, 0, 38, 0, 38, 23, 50, 24, 0, + 55, 0, 56, 34, 55, 0, 0, 35, 56, 0, + 51, 0, 58, 34, 51, 0, 23, 58, 24, 0, + 0, 59, 0, 19, 0, 0, 61, 0, 62, 0, + 62, 0, 0, 60, 57, 66, 54, 0, 10, 63, + 65, 0, 11, 64, 65, 0, 67, 0, 68, 0, + 19, 48, 25, 42, 0, 70, 0, 71, 34, 70, + 0, 0, 13, 73, 71, 14, 0, 72, 27, 74, + 28, 0, 72, 69, 0, 69, 0, 74, 69, 0, + 74, 0 }; + #endif -#if YYDEBUG || YYERROR_VERBOSE -/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "INT", "BIT", "STRING", "BITS", "LIST", - "CODE", "DAG", "CLASS", "DEF", "FIELD", "LET", "IN", "SHLTOK", "SRATOK", - "SRLTOK", "INTVAL", "ID", "VARNAME", "STRVAL", "CODEFRAGMENT", "'<'", - "'>'", "'='", "'?'", "'{'", "'}'", "'['", "']'", "'.'", "'('", "')'", - "','", "':'", "'-'", "';'", "$accept", "ClassID", "Type", "OptPrefix", - "OptValue", "Value", "OptVarName", "DagArgListNE", "DagArgList", - "RBitList", "BitList", "OptBitList", "ValueList", "ValueListNE", - "Declaration", "BodyItem", "BodyList", "Body", "SubClassRef", - "ClassListNE", "ClassList", "DeclListNE", "TemplateArgList", - "OptTemplateArgList", "OptID", "ObjectBody", "@1", "@2", "ClassInst", - "DefInst", "Object", "LETItem", "LETList", "LETCommand", "@3", - "ObjectList", "File", 0 +#if YYDEBUG != 0 +static const short yyrline[] = { 0, + 223, 234, 236, 238, 240, 242, 244, 246, 248, 252, + 252, 254, 254, 256, 258, 261, 264, 266, 279, 307, + 322, 329, 332, 339, 347, 355, 361, 367, 375, 378, + 382, 387, 393, 396, 399, 402, 415, 429, 431, 444, + 460, 462, 462, 466, 468, 472, 475, 479, 489, 491, + 497, 497, 498, 498, 500, 502, 506, 511, 516, 519, + 523, 526, 531, 532, 532, 534, 534, 536, 545, 553, + 562, 577, 582, 586, 599, 599, 601, 606, 606, 609, + 609, 612, 615, 619, 619, 621 }; #endif -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const unsigned short yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 60, 62, 61, 63, 123, 125, 91, - 93, 46, 40, 41, 44, 58, 45, 59 -}; -# endif -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const unsigned char yyr1[] = -{ - 0, 38, 39, 40, 40, 40, 40, 40, 40, 40, - 40, 41, 41, 42, 42, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 44, 44, 45, 45, 46, 46, 47, 47, 47, 47, - 47, 47, 48, 49, 49, 50, 50, 51, 51, 52, - 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, - 58, 58, 59, 59, 60, 61, 61, 62, 62, 64, - 65, 63, 66, 67, 68, 68, 69, 70, 70, 72, - 71, 68, 68, 73, 73, 74 +#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) + +static const char * const yytname[] = { "$","error","$undefined.","INT","BIT", +"STRING","BITS","LIST","CODE","DAG","CLASS","DEF","FIELD","LET","IN","SHLTOK", +"SRATOK","SRLTOK","INTVAL","ID","VARNAME","STRVAL","CODEFRAGMENT","'<'","'>'", +"'='","'?'","'{'","'}'","'['","']'","'.'","'('","')'","','","':'","'-'","';'", +"ClassID","Type","OptPrefix","OptValue","Value","OptVarName","DagArgListNE", +"DagArgList","RBitList","BitList","OptBitList","ValueList","ValueListNE","Declaration", +"BodyItem","BodyList","Body","SubClassRef","ClassListNE","ClassList","DeclListNE", +"TemplateArgList","OptTemplateArgList","OptID","ObjectName","ClassName","DefName", +"ObjectBody","@1","ClassInst","DefInst","Object","LETItem","LETList","LETCommand", +"@2","ObjectList","File", NULL }; +#endif -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const unsigned char yyr2[] = -{ - 0, 2, 1, 1, 1, 4, 1, 4, 1, 1, - 1, 0, 1, 0, 2, 1, 1, 1, 1, 3, - 4, 1, 4, 3, 3, 4, 4, 6, 6, 6, - 0, 2, 2, 4, 0, 1, 1, 3, 2, 3, - 5, 4, 1, 0, 3, 0, 1, 1, 3, 4, - 2, 6, 0, 2, 1, 3, 1, 4, 1, 3, - 0, 2, 1, 3, 3, 0, 1, 1, 0, 0, - 0, 6, 2, 2, 1, 1, 4, 1, 3, 0, - 4, 4, 2, 1, 2, 1 +static const short yyr1[] = { 0, + 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, + 40, 41, 41, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, + 44, 44, 45, 45, 46, 46, 46, 46, 46, 46, + 47, 48, 48, 49, 49, 50, 50, 51, 52, 52, + 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, + 58, 58, 59, 60, 60, 61, 61, 62, 63, 64, + 66, 65, 67, 68, 69, 69, 70, 71, 71, 73, + 72, 69, 69, 74, 74, 75 }; -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const unsigned char yydefact[] = -{ - 0, 68, 68, 79, 74, 75, 83, 0, 85, 0, - 67, 69, 72, 73, 0, 0, 82, 84, 1, 65, - 43, 77, 0, 0, 11, 66, 60, 0, 0, 80, - 0, 81, 12, 0, 62, 0, 0, 70, 36, 42, - 0, 0, 78, 6, 4, 3, 0, 0, 8, 9, - 2, 10, 0, 64, 11, 56, 58, 61, 0, 38, - 0, 0, 44, 0, 0, 0, 15, 21, 16, 17, - 18, 45, 45, 0, 76, 0, 0, 13, 63, 0, - 0, 52, 54, 71, 37, 39, 0, 0, 0, 0, - 47, 0, 46, 0, 34, 0, 0, 0, 0, 0, - 0, 49, 0, 59, 11, 41, 0, 0, 0, 0, - 0, 19, 0, 23, 30, 35, 0, 0, 0, 24, - 5, 7, 14, 57, 0, 55, 0, 53, 40, 0, - 0, 0, 20, 48, 0, 32, 0, 25, 22, 26, - 43, 50, 0, 0, 0, 31, 30, 0, 27, 28, - 29, 33, 0, 0, 51 +static const short yyr2[] = { 0, + 1, 1, 1, 4, 1, 4, 1, 1, 1, 0, + 1, 0, 2, 1, 1, 1, 1, 3, 4, 1, + 4, 3, 3, 4, 4, 6, 6, 6, 0, 2, + 2, 4, 0, 1, 1, 3, 2, 3, 5, 4, + 1, 0, 3, 0, 1, 1, 3, 4, 2, 6, + 0, 2, 1, 3, 1, 4, 1, 3, 0, 2, + 1, 3, 3, 0, 1, 1, 0, 1, 1, 1, + 0, 4, 3, 3, 1, 1, 4, 1, 3, 0, + 4, 4, 2, 1, 2, 1 }; -/* YYDEFGOTO[NTERM-NUM]. */ -static const short yydefgoto[] = -{ - -1, 51, 52, 33, 101, 90, 135, 115, 116, 39, - 40, 28, 91, 92, 34, 127, 104, 83, 56, 57, - 37, 35, 25, 26, 11, 12, 19, 58, 4, 5, - 6, 21, 22, 7, 14, 8, 9 +static const short yydefact[] = { 0, + 67, 67, 80, 75, 76, 84, 0, 86, 66, 68, + 69, 64, 70, 64, 0, 0, 83, 85, 10, 65, + 59, 73, 74, 42, 78, 0, 0, 11, 0, 61, + 0, 0, 71, 0, 0, 81, 0, 82, 5, 3, + 2, 0, 0, 7, 8, 1, 9, 0, 63, 10, + 55, 57, 60, 0, 35, 41, 0, 0, 79, 0, + 0, 12, 62, 0, 0, 51, 53, 72, 37, 0, + 0, 43, 0, 0, 0, 14, 20, 15, 16, 17, + 44, 44, 0, 77, 0, 0, 0, 48, 46, 0, + 58, 10, 36, 38, 0, 0, 0, 0, 0, 45, + 0, 33, 0, 0, 0, 4, 6, 13, 56, 0, + 0, 54, 0, 52, 40, 0, 0, 0, 0, 0, + 18, 22, 29, 34, 0, 0, 0, 23, 47, 42, + 49, 39, 0, 0, 0, 19, 0, 31, 0, 24, + 21, 25, 0, 0, 0, 0, 30, 29, 0, 26, + 27, 28, 32, 0, 50, 0, 0, 0 }; -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -61 -static const yysigned_char yypact[] = -{ - 45, -7, -7, -61, -61, -61, -61, 4, 45, 24, - -61, -61, -61, -61, 31, 45, -61, -61, -61, 29, - 46, -61, -12, -5, 62, -61, 40, 63, 68, -61, - 31, -61, -61, 57, -61, -14, 78, -61, -15, 67, - 75, 11, -61, -61, -61, -61, 84, 96, -61, -61, - -61, -61, 90, -61, 62, 97, -61, 87, 12, -61, - 104, 105, -61, 92, 93, 94, -61, 106, -61, -61, - -61, 11, 11, 108, 86, 110, 57, 107, -61, 11, - 78, -61, -61, -61, -61, -11, 11, 11, 11, 11, - 86, 102, 99, 101, 11, 63, 63, 115, 111, 112, - 11, -61, 20, -61, 6, -61, 119, -18, 65, 71, - 43, -61, 11, -61, 56, 109, 113, 114, 117, -61, - -61, -61, 86, -61, 120, -61, 103, -61, -61, 11, - 11, 11, -61, 86, 118, -61, 11, -61, -61, -61, - 46, -61, 53, 77, 85, -61, 56, 116, -61, -61, - -61, -61, 11, 41, -61 +static const short yydefgoto[] = { 47, + 48, 29, 88, 89, 138, 124, 125, 56, 57, 35, + 99, 100, 30, 114, 92, 68, 52, 53, 33, 31, + 20, 21, 10, 11, 12, 14, 22, 54, 4, 5, + 6, 25, 26, 7, 15, 8, 156 }; -/* YYPGOTO[NTERM-NUM]. */ -static const short yypgoto[] = -{ - -61, -32, 69, -61, -61, -41, -2, -61, -61, -61, - -60, 8, 79, -10, -53, -61, -61, -61, 70, -61, - -61, -61, -61, -61, -61, 147, -61, -61, -61, -61, - 34, 122, -61, -61, -61, 138, -61 +static const short yypact[] = { 52, + 15, 15,-32768,-32768,-32768,-32768, 3, 52,-32768,-32768, +-32768, 4,-32768, 4, 22, 52,-32768,-32768, 34,-32768, + -20,-32768,-32768, 28,-32768, -9, -2,-32768, 63,-32768, + -3, 37,-32768, 39, 35,-32768, 22,-32768,-32768,-32768, +-32768, 50, 51,-32768,-32768,-32768,-32768, 59,-32768, 34, + 66,-32768, 45, -15, -12, 46, 62, 32,-32768, 102, + 63, 75,-32768, 32, 37,-32768,-32768,-32768,-32768, 104, + 106,-32768, 93, 94, 95,-32768, 105,-32768,-32768,-32768, + 32, 32, 110, 77, 107, 108, 32,-32768, 77, 8, +-32768, 5,-32768, -8, 32, 32, 32, 32, 109, 96, + 103, 32, 39, 39, 115,-32768,-32768, 77,-32768, 32, + 116,-32768, 99,-32768,-32768, 120, 67, 68, 76, 11, +-32768,-32768, 57, 111, 113, 112, 114,-32768, 77, 28, +-32768,-32768, 32, 32, 32,-32768, 119,-32768, 32,-32768, +-32768,-32768, 117, 82, 85, 90,-32768, 57, 32,-32768, +-32768,-32768,-32768, 56,-32768, 141, 143,-32768 }; -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const unsigned char yytable[] = -{ - 74, 78, 29, 59, 55, 1, 2, 105, 3, 95, - 53, 96, 10, 97, 1, 2, 129, 3, 32, 124, - 54, 60, 30, 31, 18, 106, 63, 64, 65, 66, - 67, 15, 68, 69, 125, 117, 118, 70, 71, 81, - 72, 16, 17, 73, 123, 107, 108, 109, 55, 82, - 20, 126, 24, 114, 112, 1, 2, 17, 3, 122, - 43, 44, 45, 46, 47, 48, 49, 132, 95, 102, - 96, 133, 97, 27, 32, 36, 50, 112, 154, 110, - 95, 38, 96, 95, 97, 96, 148, 97, 142, 143, - 144, 134, 95, 41, 96, 146, 97, 50, 95, 130, - 96, 61, 97, 62, 95, 131, 96, 75, 97, 77, - 149, 153, 95, 95, 96, 96, 97, 97, 150, 76, - 79, 80, 84, 85, 86, 87, 88, 94, 98, 89, - 111, 113, 100, 112, 119, 120, 121, 128, 145, 140, - 141, 152, 138, 136, 151, 99, 137, 139, 147, 13, - 103, 93, 42, 23 +static const short yypgoto[] = { -25, + 86,-32768,-32768, -58, 0,-32768,-32768,-32768, -84, 19, + 69, -62, -49,-32768,-32768,-32768, 87,-32768,-32768,-32768, +-32768,-32768,-32768, 148,-32768,-32768, 139,-32768,-32768,-32768, + -4, 118,-32768,-32768,-32768, 138,-32768 }; -static const unsigned char yycheck[] = -{ - 41, 54, 14, 18, 36, 10, 11, 18, 13, 27, - 24, 29, 19, 31, 10, 11, 34, 13, 12, 13, - 34, 36, 34, 28, 0, 36, 15, 16, 17, 18, - 19, 27, 21, 22, 28, 95, 96, 26, 27, 27, - 29, 7, 8, 32, 24, 86, 87, 88, 80, 37, - 19, 104, 23, 94, 34, 10, 11, 23, 13, 100, - 3, 4, 5, 6, 7, 8, 9, 24, 27, 79, - 29, 112, 31, 27, 12, 35, 19, 34, 37, 89, - 27, 18, 29, 27, 31, 29, 33, 31, 129, 130, - 131, 35, 27, 25, 29, 136, 31, 19, 27, 34, - 29, 34, 31, 28, 27, 34, 29, 23, 31, 19, - 33, 152, 27, 27, 29, 29, 31, 31, 33, 23, - 23, 34, 18, 18, 32, 32, 32, 19, 18, 23, - 28, 30, 25, 34, 19, 24, 24, 18, 20, 19, - 37, 25, 28, 34, 146, 76, 33, 30, 140, 2, - 80, 72, 30, 15 + +#define YYLAST 155 + + +static const short yytable[] = { 84, + 63, 90, 17, 18, 36, 69, 51, 1, 2, 115, + 3, 66, 1, 2, 32, 3, 28, 111, 126, 127, + 49, 67, 18, 70, 37, 38, 19, 116, 108, 16, + 50, 109, 112, 9, 136, 120, 117, 118, 119, 51, + 24, 110, 113, 123, 110, 28, 73, 74, 75, 76, + 77, 129, 78, 79, 34, 46, 55, 80, 81, 58, + 82, 1, 2, 83, 3, 39, 40, 41, 42, 43, + 44, 45, 60, 61, 144, 145, 146, 62, 65, 71, + 148, 46, 103, 103, 104, 104, 105, 105, 64, 72, + 154, 137, 155, 103, 103, 104, 104, 105, 105, 87, + 133, 134, 103, 103, 104, 104, 105, 105, 103, 135, + 104, 103, 105, 104, 150, 105, 103, 151, 104, 85, + 105, 93, 152, 94, 95, 96, 97, 98, 102, 110, + 106, 107, 122, 128, 130, 131, 121, 132, 147, 141, + 157, 149, 158, 142, 139, 140, 86, 153, 143, 13, + 101, 91, 23, 27, 59 }; -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const unsigned char yystos[] = -{ - 0, 10, 11, 13, 66, 67, 68, 71, 73, 74, - 19, 62, 63, 63, 72, 27, 68, 68, 0, 64, - 19, 69, 70, 73, 23, 60, 61, 27, 49, 14, - 34, 28, 12, 41, 52, 59, 35, 58, 18, 47, - 48, 25, 69, 3, 4, 5, 6, 7, 8, 9, - 19, 39, 40, 24, 34, 39, 56, 57, 65, 18, - 36, 34, 28, 15, 16, 17, 18, 19, 21, 22, - 26, 27, 29, 32, 43, 23, 23, 19, 52, 23, - 34, 27, 37, 55, 18, 18, 32, 32, 32, 23, - 43, 50, 51, 50, 19, 27, 29, 31, 18, 40, - 25, 42, 51, 56, 54, 18, 36, 43, 43, 43, - 51, 28, 34, 30, 43, 45, 46, 48, 48, 19, - 24, 24, 43, 24, 13, 28, 52, 53, 18, 34, - 34, 34, 24, 43, 35, 44, 34, 33, 28, 30, - 19, 37, 43, 43, 43, 20, 43, 49, 33, 33, - 33, 44, 25, 43, 37 +static const short yycheck[] = { 58, + 50, 64, 7, 8, 14, 18, 32, 10, 11, 18, + 13, 27, 10, 11, 35, 13, 12, 13, 103, 104, + 24, 37, 27, 36, 34, 28, 23, 36, 87, 27, + 34, 24, 28, 19, 24, 98, 95, 96, 97, 65, + 19, 34, 92, 102, 34, 12, 15, 16, 17, 18, + 19, 110, 21, 22, 27, 19, 18, 26, 27, 25, + 29, 10, 11, 32, 13, 3, 4, 5, 6, 7, + 8, 9, 23, 23, 133, 134, 135, 19, 34, 34, + 139, 19, 27, 27, 29, 29, 31, 31, 23, 28, + 149, 35, 37, 27, 27, 29, 29, 31, 31, 25, + 34, 34, 27, 27, 29, 29, 31, 31, 27, 34, + 29, 27, 31, 29, 33, 31, 27, 33, 29, 18, + 31, 18, 33, 18, 32, 32, 32, 23, 19, 34, + 24, 24, 30, 19, 19, 37, 28, 18, 20, 28, + 0, 25, 0, 30, 34, 33, 61, 148, 130, 2, + 82, 65, 14, 16, 37 }; +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +#line 3 "/usr/share/bison.simple" +/* This file comes from bison-1.28. */ -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# if defined (__STDC__) || defined (__cplusplus) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int +/* Skeleton output parser for bison, + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +#ifndef YYSTACK_USE_ALLOCA +#ifdef alloca +#define YYSTACK_USE_ALLOCA +#else /* alloca not defined */ +#ifdef __GNUC__ +#define YYSTACK_USE_ALLOCA +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) +#define YYSTACK_USE_ALLOCA +#include +#else /* not sparc */ +/* We think this test detects Watcom and Microsoft C. */ +/* This used to test MSDOS, but that is a bad idea + since that symbol is in the user namespace. */ +#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) +#if 0 /* No need for malloc.h, which pollutes the namespace; + instead, just don't use alloca. */ +#include +#endif +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +/* I don't know what this was needed for, but it pollutes the namespace. + So I turned it off. rms, 2 May 1997. */ +/* #include */ + #pragma alloca +#define YYSTACK_USE_ALLOCA +#else /* not MSDOS, or __TURBOC__, or _AIX */ +#if 0 +#ifdef __hpux /* haible at ilog.fr says this works for HPUX 9.05 and up, + and on HPUX 10. Eventually we can turn this on. */ +#define YYSTACK_USE_ALLOCA +#define alloca __builtin_alloca +#endif /* __hpux */ +#endif +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc */ +#endif /* not GNU C */ +#endif /* alloca not defined */ +#endif /* YYSTACK_USE_ALLOCA not defined */ + +#ifdef YYSTACK_USE_ALLOCA +#define YYSTACK_ALLOC alloca +#else +#define YYSTACK_ALLOC malloc #endif +/* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) +#define YYEMPTY -2 #define YYEOF 0 - #define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab +#define YYABORT goto yyabortlab #define YYERROR goto yyerrlab1 - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. +/* Like YYERROR except do call yyerror. + This remains here temporarily to ease the + transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ - #define YYFAIL goto yyerrlab - #define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ +#define YYBACKUP(token, value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ + { yychar = (token), yylval = (value); \ + yychar1 = YYTRANSLATE (yychar); \ YYPOPSTACK; \ goto yybackup; \ } \ else \ - { \ - yyerror ("syntax error: cannot back up");\ - YYERROR; \ - } \ + { yyerror ("syntax error: cannot back up"); YYERROR; } \ while (0) #define YYTERROR 1 #define YYERRCODE 256 -/* YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - Current.first_line = Rhs[1].first_line; \ - Current.first_column = Rhs[1].first_column; \ - Current.last_line = Rhs[N].last_line; \ - Current.last_column = Rhs[N].last_column; +#ifndef YYPURE +#define YYLEX yylex() #endif -/* YYLEX -- calling `yylex' with the right arguments. */ - +#ifdef YYPURE +#ifdef YYLSP_NEEDED #ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) +#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) #else -# define YYLEX yylex () +#define YYLEX yylex(&yylval, &yylloc) #endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -# define YYDSYMPRINT(Args) \ -do { \ - if (yydebug) \ - yysymprint Args; \ -} while (0) - -# define YYDSYMPRINTF(Title, Token, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Token, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (cinluded). | -`------------------------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_stack_print (short *bottom, short *top) +#else /* not YYLSP_NEEDED */ +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, YYLEX_PARAM) #else -static void -yy_stack_print (bottom, top) - short *bottom; - short *top; +#define YYLEX yylex(&yylval) +#endif +#endif /* not YYLSP_NEEDED */ #endif -{ - YYFPRINTF (stderr, "Stack now"); - for (/* Nothing. */; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) +/* If nonreentrant, generate the variables here */ +#ifndef YYPURE -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ +int yychar; /* the lookahead symbol */ +YYSTYPE yylval; /* the semantic value of the */ + /* lookahead symbol */ -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_reduce_print (int yyrule) -#else -static void -yy_reduce_print (yyrule) - int yyrule; +#ifdef YYLSP_NEEDED +YYLTYPE yylloc; /* location data for the lookahead */ + /* symbol */ #endif -{ - int yyi; - unsigned int yylineno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", - yyrule - 1, yylineno); - /* Print the symbols being reduced, and their result. */ - for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) - YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); - YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); -} -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YYDSYMPRINT(Args) -# define YYDSYMPRINTF(Title, Token, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ +int yynerrs; /* number of parse errors so far */ +#endif /* not YYPURE */ + +#if YYDEBUG != 0 +int yydebug; /* nonzero means print parse trace */ +/* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ +#endif +/* YYINITDEPTH indicates the initial size of the parser's stacks */ -/* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH -# define YYINITDEPTH 200 +#define YYINITDEPTH 200 #endif -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ +/* YYMAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ #if YYMAXDEPTH == 0 -# undef YYMAXDEPTH +#undef YYMAXDEPTH #endif #ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 +#define YYMAXDEPTH 10000 #endif - +/* Define __yy_memcpy. Note that the size argument + should be passed with type unsigned int, because that is what the non-GCC + definitions require. With GCC, __builtin_memcpy takes an arg + of type size_t, but it can handle unsigned int. */ + +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) +#else /* not GNU C or C++ */ +#ifndef __cplusplus -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined (__GLIBC__) && defined (_STRING_H) -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -# if defined (__STDC__) || defined (__cplusplus) -yystrlen (const char *yystr) -# else -yystrlen (yystr) - const char *yystr; -# endif -{ - register const char *yys = yystr; - - while (*yys++ != '\0') - continue; - - return yys - yystr - 1; -} -# endif -# endif - -# ifndef yystpcpy -# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -# if defined (__STDC__) || defined (__cplusplus) -yystpcpy (char *yydest, const char *yysrc) -# else -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -# endif -{ - register char *yyd = yydest; - register const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (to, from, count) + char *to; + char *from; + unsigned int count; +{ + register char *f = from; + register char *t = to; + register int i = count; - return yyd - 1; + while (i-- > 0) + *t++ = *f++; } -# endif -# endif - -#endif /* !YYERROR_VERBOSE */ - - -#if YYDEBUG -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +#else /* __cplusplus */ -#if defined (__STDC__) || defined (__cplusplus) -static void -yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -#else +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ static void -yysymprint (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE *yyvaluep; -#endif +__yy_memcpy (char *to, char *from, unsigned int count) { - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - if (yytype < YYNTOKENS) - { - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -# ifdef YYPRINT - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - } - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + register char *t = to; + register char *f = from; + register int i = count; - switch (yytype) - { - default: - break; - } - YYFPRINTF (yyoutput, ")"); + while (i-- > 0) + *t++ = *f++; } -#endif /* ! YYDEBUG */ -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yydestruct (int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yytype, yyvaluep) - int yytype; - YYSTYPE *yyvaluep; #endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - switch (yytype) - { - - default: - break; - } -} +#endif +#line 217 "/usr/share/bison.simple" -/* Prevent warnings from -Wmissing-prototypes. */ +/* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. + It should actually point to an object. + Grammar actions can access the variable by casting it + to the proper pointer type. */ #ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM); -# else -int yyparse (); -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - - -/*----------. -| yyparse. | -`----------*/ +#ifdef __cplusplus +#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM +#define YYPARSE_PARAM_DECL +#else /* not __cplusplus */ +#define YYPARSE_PARAM_ARG YYPARSE_PARAM +#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; +#endif /* not __cplusplus */ +#else /* not YYPARSE_PARAM */ +#define YYPARSE_PARAM_ARG +#define YYPARSE_PARAM_DECL +#endif /* not YYPARSE_PARAM */ +/* Prevent warning if -Wstrict-prototypes. */ +#ifdef __GNUC__ #ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM) -# else -int yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int -yyparse (void) +int yyparse (void *); #else -int -yyparse () - +int yyparse (void); #endif #endif + +int +yyparse(YYPARSE_PARAM_ARG) + YYPARSE_PARAM_DECL { - register int yystate; register int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - short yyssa[YYINITDEPTH]; - short *yyss = yyssa; register short *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; register YYSTYPE *yyvsp; + int yyerrstatus; /* number of tokens to shift before error messages enabled */ + int yychar1 = 0; /* lookahead token as an internal (translated) token number */ + + short yyssa[YYINITDEPTH]; /* the state stack */ + YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ +#ifdef YYLSP_NEEDED + YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; +#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) +#else #define YYPOPSTACK (yyvsp--, yyssp--) +#endif - YYSIZE_T yystacksize = YYINITDEPTH; + int yystacksize = YYINITDEPTH; + int yyfree_stacks = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; +#ifdef YYPURE + int yychar; + YYSTYPE yylval; + int yynerrs; +#ifdef YYLSP_NEEDED + YYLTYPE yylloc; +#endif +#endif + YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ - /* When reducing, the number of symbols on the RHS of the reduced - rule. */ int yylen; - YYDPRINTF ((stderr, "Starting parse\n")); +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Starting parse\n"); +#endif yystate = 0; yyerrstatus = 0; @@ -1148,96 +764,110 @@ so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss; + yyssp = yyss - 1; yyvsp = yyvs; +#ifdef YYLSP_NEEDED + yylsp = yyls; +#endif - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. - */ - yyssp++; +/* Push a new state, which is found in yystate . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +yynewstate: - yysetstate: - *yyssp = yystate; + *++yyssp = yystate; - if (yyss + yystacksize - 1 <= yyssp) + if (yyssp >= yyss + yystacksize - 1) { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; +#ifdef YYLSP_NEEDED + YYLTYPE *yyls1 = yyls; +#endif + /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + int size = yyssp - yyss + 1; #ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ +#ifdef YYLSP_NEEDED + /* This used to be a conditional around just the two extra args, + but that might be undefined if yyoverflow is a macro. */ + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yyls1, size * sizeof (*yylsp), + &yystacksize); +#else + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yystacksize); +#endif - yyss = yyss1; - yyvs = yyvs1; - } + yyss = yyss1; yyvs = yyvs1; +#ifdef YYLSP_NEEDED + yyls = yyls1; +#endif #else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyoverflowlab; -# else /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyoverflowlab; + if (yystacksize >= YYMAXDEPTH) + { + yyerror("parser stack overflow"); + if (yyfree_stacks) + { + free (yyss); + free (yyvs); +#ifdef YYLSP_NEEDED + free (yyls); +#endif + } + return 2; + } yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) + if (yystacksize > YYMAXDEPTH) yystacksize = YYMAXDEPTH; - - { - short *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif +#ifndef YYSTACK_USE_ALLOCA + yyfree_stacks = 1; +#endif + yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); + __yy_memcpy ((char *)yyss, (char *)yyss1, + size * (unsigned int) sizeof (*yyssp)); + yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); + __yy_memcpy ((char *)yyvs, (char *)yyvs1, + size * (unsigned int) sizeof (*yyvsp)); +#ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); + __yy_memcpy ((char *)yyls, (char *)yyls1, + size * (unsigned int) sizeof (*yylsp)); +#endif #endif /* no yyoverflow */ - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - + yyssp = yyss + size - 1; + yyvsp = yyvs + size - 1; +#ifdef YYLSP_NEEDED + yylsp = yyls + size - 1; +#endif - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Stack size increased to %d\n", yystacksize); +#endif - if (yyss + yystacksize - 1 <= yyssp) + if (yyssp >= yyss + yystacksize - 1) YYABORT; } - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Entering state %d\n", yystate); +#endif goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: + yybackup: /* Do appropriate processing given the current state. */ /* Read a lookahead token if we need one and don't already have one. */ @@ -1246,217 +876,236 @@ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) + if (yyn == YYFLAG) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + if (yychar == YYEMPTY) { - YYDPRINTF ((stderr, "Reading a token: ")); +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Reading a token: "); +#endif yychar = YYLEX; } - if (yychar <= YYEOF) + /* Convert token to internal form (in yychar1) for indexing tables with */ + + if (yychar <= 0) /* This means end of input. */ { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); + yychar1 = 0; + yychar = YYEOF; /* Don't call YYLEX any more */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Now at end of input.\n"); +#endif } else { - yytoken = YYTRANSLATE (yychar); - YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + yychar1 = YYTRANSLATE(yychar); + +#if YYDEBUG != 0 + if (yydebug) + { + fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ +#ifdef YYPRINT + YYPRINT (stderr, yychar, yylval); +#endif + fprintf (stderr, ")\n"); + } +#endif } - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) goto yydefault; + yyn = yytable[yyn]; - if (yyn <= 0) + + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (yyn < 0) { - if (yyn == 0 || yyn == YYTABLE_NINF) + if (yyn == YYFLAG) goto yyerrlab; yyn = -yyn; goto yyreduce; } + else if (yyn == 0) + goto yyerrlab; if (yyn == YYFINAL) YYACCEPT; /* Shift the lookahead token. */ - YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); +#endif /* Discard the token being shifted unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; + /* count tokens shifted since error; after three, turn off error status. */ + if (yyerrstatus) yyerrstatus--; yystate = yyn; goto yynewstate; - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ +/* Do the default action for the current state. */ yydefault: + yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; - goto yyreduce; - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ +/* Do a reduction. yyn is the number of a rule to reduce with. */ yyreduce: - /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; + if (yylen > 0) + yyval = yyvsp[1-yylen]; /* implement default value of the action */ + +#if YYDEBUG != 0 + if (yydebug) + { + int i; - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. + fprintf (stderr, "Reducing via rule %d (line %d), ", + yyn, yyrline[yyn]); - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; + /* Print the symbols being reduced, and their result. */ + for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) + fprintf (stderr, "%s ", yytname[yyrhs[i]]); + fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); + } +#endif - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -#line 223 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + switch (yyn) { + +case 1: +#line 223 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.Rec = Records.getClass(*yyvsp[0].StrVal); if (yyval.Rec == 0) { err() << "Couldn't find class '" << *yyvsp[0].StrVal << "'!\n"; exit(1); } delete yyvsp[0].StrVal; - ;} - break; - - case 3: -#line 234 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { // string type + ; + break;} +case 2: +#line 234 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ // string type yyval.Ty = new StringRecTy(); - ;} - break; - - case 4: -#line 236 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { // bit type + ; + break;} +case 3: +#line 236 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ // bit type yyval.Ty = new BitRecTy(); - ;} - break; - - case 5: -#line 238 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { // bits type + ; + break;} +case 4: +#line 238 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ // bits type yyval.Ty = new BitsRecTy(yyvsp[-1].IntVal); - ;} - break; - - case 6: -#line 240 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { // int type + ; + break;} +case 5: +#line 240 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ // int type yyval.Ty = new IntRecTy(); - ;} - break; - - case 7: -#line 242 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { // list type + ; + break;} +case 6: +#line 242 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ // list type yyval.Ty = new ListRecTy(yyvsp[-1].Ty); - ;} - break; - - case 8: -#line 244 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { // code type + ; + break;} +case 7: +#line 244 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ // code type yyval.Ty = new CodeRecTy(); - ;} - break; - - case 9: -#line 246 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { // dag type + ; + break;} +case 8: +#line 246 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ // dag type yyval.Ty = new DagRecTy(); - ;} - break; - - case 10: -#line 248 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { // Record Type + ; + break;} +case 9: +#line 248 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ // Record Type yyval.Ty = new RecordRecTy(yyvsp[0].Rec); - ;} - break; - - case 11: -#line 252 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { yyval.IntVal = 0; ;} - break; - - case 12: -#line 252 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { yyval.IntVal = 1; ;} - break; - - case 13: -#line 254 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { yyval.Initializer = 0; ;} - break; - - case 14: -#line 254 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { yyval.Initializer = yyvsp[0].Initializer; ;} - break; - - case 15: -#line 256 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 10: +#line 252 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.IntVal = 0; ; + break;} +case 11: +#line 252 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.IntVal = 1; ; + break;} +case 12: +#line 254 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = 0; ; + break;} +case 13: +#line 254 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = yyvsp[0].Initializer; ; + break;} +case 14: +#line 256 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = new IntInit(yyvsp[0].IntVal); - ;} - break; - - case 16: -#line 258 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 15: +#line 258 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = new StringInit(*yyvsp[0].StrVal); delete yyvsp[0].StrVal; - ;} - break; - - case 17: -#line 261 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 16: +#line 261 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = new CodeInit(*yyvsp[0].StrVal); delete yyvsp[0].StrVal; - ;} - break; - - case 18: -#line 264 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 17: +#line 264 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = new UnsetInit(); - ;} - break; - - case 19: -#line 266 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 18: +#line 266 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ BitsInit *Init = new BitsInit(yyvsp[-1].FieldList->size()); for (unsigned i = 0, e = yyvsp[-1].FieldList->size(); i != e; ++i) { struct Init *Bit = (*yyvsp[-1].FieldList)[i]->convertInitializerTo(new BitRecTy()); @@ -1469,12 +1118,11 @@ } yyval.Initializer = Init; delete yyvsp[-1].FieldList; - ;} - break; - - case 20: -#line 279 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 19: +#line 279 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ // This is a CLASS expression. This is supposed to synthesize // a new anonymous definition, deriving from CLASS with no // body. @@ -1502,12 +1150,11 @@ // Restore the old CurRec CurRec = OldRec; - ;} - break; - - case 21: -#line 307 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 20: +#line 307 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ if (const RecordVal *RV = (CurRec ? CurRec->getValue(*yyvsp[0].StrVal) : 0)) { yyval.Initializer = new VarInit(*yyvsp[0].StrVal, RV->getType()); } else if (CurRec && CurRec->isTemplateArg(CurRec->getName()+":"+*yyvsp[0].StrVal)) { @@ -1522,44 +1169,40 @@ } delete yyvsp[0].StrVal; - ;} - break; - - case 22: -#line 322 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 21: +#line 322 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = yyvsp[-3].Initializer->convertInitializerBitRange(*yyvsp[-1].BitList); if (yyval.Initializer == 0) { err() << "Invalid bit range for value '" << *yyvsp[-3].Initializer << "'!\n"; exit(1); } delete yyvsp[-1].BitList; - ;} - break; - - case 23: -#line 329 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 22: +#line 329 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = new ListInit(*yyvsp[-1].FieldList); delete yyvsp[-1].FieldList; - ;} - break; - - case 24: -#line 332 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 23: +#line 332 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ if (!yyvsp[-2].Initializer->getFieldType(*yyvsp[0].StrVal)) { err() << "Cannot access field '" << *yyvsp[0].StrVal << "' of value '" << *yyvsp[-2].Initializer << "!\n"; exit(1); } yyval.Initializer = new FieldInit(yyvsp[-2].Initializer, *yyvsp[0].StrVal); delete yyvsp[0].StrVal; - ;} - break; - - case 25: -#line 339 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 24: +#line 339 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ Record *D = Records.getDef(*yyvsp[-2].StrVal); if (D == 0) { err() << "Invalid def '" << *yyvsp[-2].StrVal << "'!\n"; @@ -1567,12 +1210,11 @@ } yyval.Initializer = new DagInit(D, *yyvsp[-1].DagValueList); delete yyvsp[-2].StrVal; delete yyvsp[-1].DagValueList; - ;} - break; - - case 26: -#line 347 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 25: +#line 347 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ std::reverse(yyvsp[-1].BitList->begin(), yyvsp[-1].BitList->end()); yyval.Initializer = yyvsp[-3].Initializer->convertInitListSlice(*yyvsp[-1].BitList); if (yyval.Initializer == 0) { @@ -1580,97 +1222,86 @@ exit(1); } delete yyvsp[-1].BitList; - ;} - break; - - case 27: -#line 355 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 26: +#line 355 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = yyvsp[-3].Initializer->getBinaryOp(Init::SHL, yyvsp[-1].Initializer); if (yyval.Initializer == 0) { err() << "Cannot shift values '" << *yyvsp[-3].Initializer << "' and '" << *yyvsp[-1].Initializer << "'!\n"; exit(1); } - ;} - break; - - case 28: -#line 361 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 27: +#line 361 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = yyvsp[-3].Initializer->getBinaryOp(Init::SRA, yyvsp[-1].Initializer); if (yyval.Initializer == 0) { err() << "Cannot shift values '" << *yyvsp[-3].Initializer << "' and '" << *yyvsp[-1].Initializer << "'!\n"; exit(1); } - ;} - break; - - case 29: -#line 367 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 28: +#line 367 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = yyvsp[-3].Initializer->getBinaryOp(Init::SRL, yyvsp[-1].Initializer); if (yyval.Initializer == 0) { err() << "Cannot shift values '" << *yyvsp[-3].Initializer << "' and '" << *yyvsp[-1].Initializer << "'!\n"; exit(1); } - ;} - break; - - case 30: -#line 375 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 29: +#line 375 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.StrVal = new std::string(); - ;} - break; - - case 31: -#line 378 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 30: +#line 378 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.StrVal = yyvsp[0].StrVal; - ;} - break; - - case 32: -#line 382 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 31: +#line 382 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.DagValueList = new std::vector >(); yyval.DagValueList->push_back(std::make_pair(yyvsp[-1].Initializer, *yyvsp[0].StrVal)); delete yyvsp[0].StrVal; - ;} - break; - - case 33: -#line 387 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 32: +#line 387 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyvsp[-3].DagValueList->push_back(std::make_pair(yyvsp[-1].Initializer, *yyvsp[0].StrVal)); delete yyvsp[0].StrVal; yyval.DagValueList = yyvsp[-3].DagValueList; - ;} - break; - - case 34: -#line 393 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 33: +#line 393 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.DagValueList = new std::vector >(); - ;} - break; - - case 35: -#line 396 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { yyval.DagValueList = yyvsp[0].DagValueList; ;} - break; - - case 36: -#line 399 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 34: +#line 396 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.DagValueList = yyvsp[0].DagValueList; ; + break;} +case 35: +#line 399 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.BitList = new std::vector(); yyval.BitList->push_back(yyvsp[0].IntVal); - ;} - break; - - case 37: -#line 402 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 36: +#line 402 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ if (yyvsp[-2].IntVal < 0 || yyvsp[0].IntVal < 0) { err() << "Invalid range: " << yyvsp[-2].IntVal << "-" << yyvsp[0].IntVal << "!\n"; exit(1); @@ -1683,12 +1314,11 @@ for (int i = yyvsp[-2].IntVal; i >= yyvsp[0].IntVal; --i) yyval.BitList->push_back(i); } - ;} - break; - - case 38: -#line 415 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 37: +#line 415 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyvsp[0].IntVal = -yyvsp[0].IntVal; if (yyvsp[-1].IntVal < 0 || yyvsp[0].IntVal < 0) { err() << "Invalid range: " << yyvsp[-1].IntVal << "-" << yyvsp[0].IntVal << "!\n"; @@ -1702,19 +1332,17 @@ for (int i = yyvsp[-1].IntVal; i >= yyvsp[0].IntVal; --i) yyval.BitList->push_back(i); } - ;} - break; - - case 39: -#line 429 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 38: +#line 429 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ (yyval.BitList=yyvsp[-2].BitList)->push_back(yyvsp[0].IntVal); - ;} - break; - - case 40: -#line 431 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 39: +#line 431 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ if (yyvsp[-2].IntVal < 0 || yyvsp[0].IntVal < 0) { err() << "Invalid range: " << yyvsp[-2].IntVal << "-" << yyvsp[0].IntVal << "!\n"; exit(1); @@ -1727,12 +1355,11 @@ for (int i = yyvsp[-2].IntVal; i >= yyvsp[0].IntVal; --i) yyval.BitList->push_back(i); } - ;} - break; - - case 41: -#line 444 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 40: +#line 444 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyvsp[0].IntVal = -yyvsp[0].IntVal; if (yyvsp[-1].IntVal < 0 || yyvsp[0].IntVal < 0) { err() << "Invalid range: " << yyvsp[-1].IntVal << "-" << yyvsp[0].IntVal << "!\n"; @@ -1746,56 +1373,48 @@ for (int i = yyvsp[-1].IntVal; i >= yyvsp[0].IntVal; --i) yyval.BitList->push_back(i); } - ;} - break; - - case 42: -#line 460 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { yyval.BitList = yyvsp[0].BitList; std::reverse(yyvsp[0].BitList->begin(), yyvsp[0].BitList->end()); ;} - break; - - case 43: -#line 462 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { yyval.BitList = 0; ;} - break; - - case 44: -#line 462 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { yyval.BitList = yyvsp[-1].BitList; ;} - break; - - case 45: -#line 466 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 41: +#line 460 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.BitList = yyvsp[0].BitList; std::reverse(yyvsp[0].BitList->begin(), yyvsp[0].BitList->end()); ; + break;} +case 42: +#line 462 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.BitList = 0; ; + break;} +case 43: +#line 462 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.BitList = yyvsp[-1].BitList; ; + break;} +case 44: +#line 466 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.FieldList = new std::vector(); - ;} - break; - - case 46: -#line 468 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 45: +#line 468 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.FieldList = yyvsp[0].FieldList; - ;} - break; - - case 47: -#line 472 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 46: +#line 472 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.FieldList = new std::vector(); yyval.FieldList->push_back(yyvsp[0].Initializer); - ;} - break; - - case 48: -#line 475 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 47: +#line 475 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ (yyval.FieldList = yyvsp[-2].FieldList)->push_back(yyvsp[0].Initializer); - ;} - break; - - case 49: -#line 479 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 48: +#line 479 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ std::string DecName = *yyvsp[-1].StrVal; if (ParsingTemplateArgs) DecName = CurRec->getName() + ":" + DecName; @@ -1803,116 +1422,122 @@ addValue(RecordVal(DecName, yyvsp[-2].Ty, yyvsp[-3].IntVal)); setValue(DecName, 0, yyvsp[0].Initializer); yyval.StrVal = new std::string(DecName); -;} - break; - - case 50: -#line 489 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 49: +#line 489 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ delete yyvsp[-1].StrVal; -;} - break; - - case 51: -#line 491 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 50: +#line 491 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ setValue(*yyvsp[-4].StrVal, yyvsp[-3].BitList, yyvsp[-1].Initializer); delete yyvsp[-4].StrVal; delete yyvsp[-3].BitList; -;} - break; - - case 56: -#line 500 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 55: +#line 500 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.SubClassRef = new SubClassRefTy(yyvsp[0].Rec, new std::vector()); - ;} - break; - - case 57: -#line 502 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 56: +#line 502 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.SubClassRef = new SubClassRefTy(yyvsp[-3].Rec, yyvsp[-1].FieldList); - ;} - break; - - case 58: -#line 506 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 57: +#line 506 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.SubClassList = new std::vector(); yyval.SubClassList->push_back(*yyvsp[0].SubClassRef); delete yyvsp[0].SubClassRef; - ;} - break; - - case 59: -#line 511 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 58: +#line 511 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ (yyval.SubClassList=yyvsp[-2].SubClassList)->push_back(*yyvsp[0].SubClassRef); delete yyvsp[0].SubClassRef; - ;} - break; - - case 60: -#line 516 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 59: +#line 516 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.SubClassList = new std::vector(); - ;} - break; - - case 61: -#line 519 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 60: +#line 519 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.SubClassList = yyvsp[0].SubClassList; - ;} - break; - - case 62: -#line 523 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 61: +#line 523 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ CurRec->addTemplateArg(*yyvsp[0].StrVal); delete yyvsp[0].StrVal; -;} - break; - - case 63: -#line 526 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 62: +#line 526 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ CurRec->addTemplateArg(*yyvsp[0].StrVal); delete yyvsp[0].StrVal; -;} - break; - - case 64: -#line 531 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - {;} - break; - - case 67: -#line 534 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { yyval.StrVal = yyvsp[0].StrVal; ;} - break; - - case 68: -#line 534 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { yyval.StrVal = new std::string(); ;} - break; - - case 69: -#line 536 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { - static unsigned AnonCounter = 0; - if (yyvsp[0].StrVal->empty()) - *yyvsp[0].StrVal = "anonymous."+utostr(AnonCounter++); - CurRec = new Record(*yyvsp[0].StrVal); - delete yyvsp[0].StrVal; - ParsingTemplateArgs = true; - ;} - break; - - case 70: -#line 543 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 63: +#line 531 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{; + break;} +case 66: +#line 534 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.StrVal = yyvsp[0].StrVal; ; + break;} +case 67: +#line 534 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.StrVal = new std::string(); ; + break;} +case 68: +#line 536 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ + static unsigned AnonCounter = 0; + if (yyvsp[0].StrVal->empty()) + *yyvsp[0].StrVal = "anonymous."+utostr(AnonCounter++); + CurRec = new Record(*yyvsp[0].StrVal); + delete yyvsp[0].StrVal; + ParsingTemplateArgs = true; +; + break;} +case 69: +#line 545 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ + if (Records.getClass(CurRec->getName())) { + err() << "Class '" << CurRec->getName() << "' already defined!\n"; + exit(1); + } + Records.addClass(CurRec); +; + break;} +case 70: +#line 553 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ + // Ensure redefinition doesn't happen. + if (Records.getDef(CurRec->getName())) { + err() << "Def '" << CurRec->getName() << "' already defined!\n"; + exit(1); + } + Records.addDef(CurRec); +; + break;} +case 71: +#line 562 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ ParsingTemplateArgs = false; for (unsigned i = 0, e = yyvsp[0].SubClassList->size(); i != e; ++i) { addSubClass((*yyvsp[0].SubClassList)[i].first, *(*yyvsp[0].SubClassList)[i].second); @@ -1927,31 +1552,24 @@ setValue(LetStack[i][j].Name, LetStack[i][j].HasBits ? &LetStack[i][j].Bits : 0, LetStack[i][j].Value); - ;} - break; - - case 71: -#line 558 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 72: +#line 577 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyval.Rec = CurRec; CurRec = 0; - ;} - break; - - case 72: -#line 563 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { - if (Records.getClass(yyvsp[0].Rec->getName())) { - err() << "Class '" << yyvsp[0].Rec->getName() << "' already defined!\n"; - exit(1); - } - Records.addClass(yyval.Rec = yyvsp[0].Rec); -;} - break; - - case 73: -#line 571 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 73: +#line 582 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ + yyval.Rec = yyvsp[0].Rec; +; + break;} +case 74: +#line 586 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ yyvsp[0].Rec->resolveReferences(); // If ObjectBody has template arguments, it's an error. @@ -1960,260 +1578,270 @@ << "' is not permitted to have template arguments!\n"; exit(1); } - // Ensure redefinition doesn't happen. - if (Records.getDef(yyvsp[0].Rec->getName())) { - err() << "Def '" << yyvsp[0].Rec->getName() << "' already defined!\n"; - exit(1); - } - Records.addDef(yyval.Rec = yyvsp[0].Rec); -;} - break; - - case 76: -#line 591 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + yyval.Rec = yyvsp[0].Rec; +; + break;} +case 77: +#line 601 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ LetStack.back().push_back(LetRecord(*yyvsp[-3].StrVal, yyvsp[-2].BitList, yyvsp[0].Initializer)); delete yyvsp[-3].StrVal; delete yyvsp[-2].BitList; -;} - break; - - case 79: -#line 599 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { LetStack.push_back(std::vector()); ;} - break; - - case 81: -#line 602 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 80: +#line 609 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ LetStack.push_back(std::vector()); ; + break;} +case 82: +#line 612 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ LetStack.pop_back(); - ;} - break; - - case 82: -#line 605 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 83: +#line 615 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ LetStack.pop_back(); - ;} - break; - - case 83: -#line 609 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - {;} - break; - - case 84: -#line 609 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - {;} - break; - - case 85: -#line 611 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" - {;} - break; - - - } - -/* Line 999 of yacc.c. */ -#line 2018 "FileParser.tab.c" + ; + break;} +case 84: +#line 619 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{; + break;} +case 85: +#line 619 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{; + break;} +case 86: +#line 621 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{; + break;} +} + /* the action file gets copied in in place of this dollarsign */ +#line 543 "/usr/share/bison.simple" yyvsp -= yylen; yyssp -= yylen; +#ifdef YYLSP_NEEDED + yylsp -= yylen; +#endif - - YY_STACK_PRINT (yyss, yyssp); +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif *++yyvsp = yyval; +#ifdef YYLSP_NEEDED + yylsp++; + if (yylen == 0) + { + yylsp->first_line = yylloc.first_line; + yylsp->first_column = yylloc.first_column; + yylsp->last_line = (yylsp-1)->last_line; + yylsp->last_column = (yylsp-1)->last_column; + yylsp->text = 0; + } + else + { + yylsp->last_line = (yylsp+yylen-1)->last_line; + yylsp->last_column = (yylsp+yylen-1)->last_column; + } +#endif - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ yyn = yyr1[yyn]; - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else - yystate = yydefgoto[yyn - YYNTOKENS]; + yystate = yydefgoto[yyn - YYNTBASE]; goto yynewstate; +yyerrlab: /* here on detecting error */ -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) + if (! yyerrstatus) + /* If not already recovering from an error, report this error. */ { ++yynerrs; -#if YYERROR_VERBOSE + +#ifdef YYERROR_VERBOSE yyn = yypact[yystate]; - if (YYPACT_NINF < yyn && yyn < YYLAST) + if (yyn > YYFLAG && yyn < YYLAST) { - YYSIZE_T yysize = 0; - int yytype = YYTRANSLATE (yychar); - char *yymsg; - int yyx, yycount; - - yycount = 0; - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - yysize += yystrlen (yytname[yyx]) + 15, yycount++; - yysize += yystrlen ("syntax error, unexpected ") + 1; - yysize += yystrlen (yytname[yytype]); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) + int size = 0; + char *msg; + int x, count; + + count = 0; + /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + size += strlen(yytname[x]) + 15, count++; + msg = (char *) malloc(size + 15); + if (msg != 0) { - char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); - yyp = yystpcpy (yyp, yytname[yytype]); + strcpy(msg, "parse error"); - if (yycount < 5) + if (count < 5) { - yycount = 0; - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); - yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + count = 0; + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) { - const char *yyq = ! yycount ? ", expecting " : " or "; - yyp = yystpcpy (yyp, yyq); - yyp = yystpcpy (yyp, yytname[yyx]); - yycount++; + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, yytname[x]); + strcat(msg, "'"); + count++; } } - yyerror (yymsg); - YYSTACK_FREE (yymsg); + yyerror(msg); + free(msg); } else - yyerror ("syntax error; also virtual memory exhausted"); + yyerror ("parse error; also virtual memory exceeded"); } else #endif /* YYERROR_VERBOSE */ - yyerror ("syntax error"); + yyerror("parse error"); } - + goto yyerrlab1; +yyerrlab1: /* here on error raised explicitly by an action */ if (yyerrstatus == 3) { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ + /* if just tried and failed to reuse lookahead token after an error, discard it. */ - /* Return failure if at end of input. */ + /* return failure if at end of input */ if (yychar == YYEOF) - { - /* Pop the error token. */ - YYPOPSTACK; - /* Pop the rest of the stack. */ - while (yyss < yyssp) - { - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[*yyssp], yyvsp); - YYPOPSTACK; - } - YYABORT; - } + YYABORT; - YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); - yydestruct (yytoken, &yylval); - yychar = YYEMPTY; +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); +#endif + yychar = YYEMPTY; } - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; + /* Else will try to reuse lookahead token + after shifting the error token. */ + + yyerrstatus = 3; /* Each real token shifted decrements this */ + + goto yyerrhandle; + +yyerrdefault: /* current state does not do anything special for the error token. */ +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (yyn) goto yydefault; +#endif + +yyerrpop: /* pop the current state because it cannot handle the error token */ -/*----------------------------------------------------. -| yyerrlab1 -- error raised explicitly by an action. | -`----------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + if (yyssp == yyss) YYABORT; + yyvsp--; + yystate = *--yyssp; +#ifdef YYLSP_NEEDED + yylsp--; +#endif - for (;;) +#if YYDEBUG != 0 + if (yydebug) { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + short *ssp1 = yyss - 1; + fprintf (stderr, "Error: state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; +yyerrhandle: - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[yystate], yyvsp); - yyvsp--; - yystate = *--yyssp; + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; + + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; - YY_STACK_PRINT (yyss, yyssp); + yyn = yytable[yyn]; + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrpop; + yyn = -yyn; + goto yyreduce; } + else if (yyn == 0) + goto yyerrpop; if (yyn == YYFINAL) YYACCEPT; - YYDPRINTF ((stderr, "Shifting error token, ")); +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting error token, "); +#endif *++yyvsp = yylval; - +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif yystate = yyn; goto yynewstate; + yyacceptlab: + /* YYACCEPT comes here. */ + if (yyfree_stacks) + { + free (yyss); + free (yyvs); +#ifdef YYLSP_NEEDED + free (yyls); +#endif + } + return 0; -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*----------------------------------------------. -| yyoverflowlab -- parser overflow comes here. | -`----------------------------------------------*/ -yyoverflowlab: - yyerror ("parser stack overflow"); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); + yyabortlab: + /* YYABORT comes here. */ + if (yyfree_stacks) + { + free (yyss); + free (yyvs); +#ifdef YYLSP_NEEDED + free (yyls); #endif - return yyresult; + } + return 1; } - - -#line 613 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" +#line 623 "/Users/sabre/llvm/utils/TableGen/FileParser.y" int yyerror(const char *ErrorMsg) { err() << "Error parsing: " << ErrorMsg << "\n"; exit(1); } - Index: llvm/utils/TableGen/FileParser.h diff -u llvm/utils/TableGen/FileParser.h:1.3 llvm/utils/TableGen/FileParser.h:1.4 --- llvm/utils/TableGen/FileParser.h:1.3 Mon Sep 12 00:30:06 2005 +++ llvm/utils/TableGen/FileParser.h Thu Sep 29 23:11:27 2005 @@ -1,83 +1,4 @@ -/* A Bison parser, made by GNU Bison 1.875. */ - -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - INT = 258, - BIT = 259, - STRING = 260, - BITS = 261, - LIST = 262, - CODE = 263, - DAG = 264, - CLASS = 265, - DEF = 266, - FIELD = 267, - LET = 268, - IN = 269, - SHLTOK = 270, - SRATOK = 271, - SRLTOK = 272, - INTVAL = 273, - ID = 274, - VARNAME = 275, - STRVAL = 276, - CODEFRAGMENT = 277 - }; -#endif -#define INT 258 -#define BIT 259 -#define STRING 260 -#define BITS 261 -#define LIST 262 -#define CODE 263 -#define DAG 264 -#define CLASS 265 -#define DEF 266 -#define FIELD 267 -#define LET 268 -#define IN 269 -#define SHLTOK 270 -#define SRATOK 271 -#define SRLTOK 272 -#define INTVAL 273 -#define ID 274 -#define VARNAME 275 -#define STRVAL 276 -#define CODEFRAGMENT 277 - - - - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 189 "/home/vadve/lattner/llvm/utils/TableGen/FileParser.y" -typedef union YYSTYPE { +typedef union { std::string* StrVal; int IntVal; llvm::RecTy* Ty; @@ -89,14 +10,26 @@ std::vector* SubClassList; std::vector >* DagValueList; } YYSTYPE; -/* Line 1240 of yacc.c. */ -#line 93 "FileParser.tab.h" -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE Filelval; - +#define INT 257 +#define BIT 258 +#define STRING 259 +#define BITS 260 +#define LIST 261 +#define CODE 262 +#define DAG 263 +#define CLASS 264 +#define DEF 265 +#define FIELD 266 +#define LET 267 +#define IN 268 +#define SHLTOK 269 +#define SRATOK 270 +#define SRLTOK 271 +#define INTVAL 272 +#define ID 273 +#define VARNAME 274 +#define STRVAL 275 +#define CODEFRAGMENT 276 +extern YYSTYPE Filelval; From lattner at cs.uiuc.edu Thu Sep 29 23:13:35 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 23:13:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200509300413.XAA15490@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.49 -> 1.50 --- Log message: Now that self referential classes are supported, get rid of a work-around. --- Diffs of the changes: (+6 -4) Target.td | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.49 llvm/lib/Target/Target.td:1.50 --- llvm/lib/Target/Target.td:1.49 Fri Aug 26 15:55:20 2005 +++ llvm/lib/Target/Target.td Thu Sep 29 23:13:23 2005 @@ -46,7 +46,7 @@ // Register - You should define one instance of this class for each register // in the target machine. String n will become the "name" of the register. -class RegisterBase { +class Register { string Namespace = ""; string Name = n; @@ -60,10 +60,12 @@ // spilling the register. Like SpillSize, this should only be explicitly // specified if the register is not in a register class. int SpillAlignment = 0; -} -class Register : RegisterBase { - list Aliases = []; + // Aliases - A list of registers that this register overlaps with. A read or + // modification of this register can potentially read or modifie the aliased + // registers. + // + list Aliases = []; } // RegisterGroup - This can be used to define instances of Register which From lattner at cs.uiuc.edu Thu Sep 29 23:42:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 23:42:44 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.y Message-ID: <200509300442.XAA15993@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.y updated: 1.37 -> 1.38 --- Log message: Generate a parse error instead of a checked exception if template args are used on a def. --- Diffs of the changes: (+10 -14) FileParser.y | 24 ++++++++++-------------- 1 files changed, 10 insertions(+), 14 deletions(-) Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.37 llvm/utils/TableGen/FileParser.y:1.38 --- llvm/utils/TableGen/FileParser.y:1.37 Thu Sep 29 23:10:49 2005 +++ llvm/utils/TableGen/FileParser.y Thu Sep 29 23:42:31 2005 @@ -559,15 +559,15 @@ Records.addDef(CurRec); }; -ObjectBody : OptTemplateArgList ClassList { +ObjectBody : ClassList { ParsingTemplateArgs = false; - for (unsigned i = 0, e = $2->size(); i != e; ++i) { - addSubClass((*$2)[i].first, *(*$2)[i].second); + for (unsigned i = 0, e = $1->size(); i != e; ++i) { + addSubClass((*$1)[i].first, *(*$1)[i].second); // Delete the template arg values for the class - delete (*$2)[i].second; + delete (*$1)[i].second; } - delete $2; // Delete the class list... - + delete $1; // Delete the class list... + // Process any variables on the set stack... for (unsigned i = 0, e = LetStack.size(); i != e; ++i) for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) @@ -579,19 +579,15 @@ CurRec = 0; }; -ClassInst : CLASS ClassName ObjectBody { - $$ = $3; -}; +ClassInst : CLASS ClassName OptTemplateArgList ObjectBody { + $$ = $4; + }; DefInst : DEF DefName ObjectBody { $3->resolveReferences(); // If ObjectBody has template arguments, it's an error. - if (!$3->getTemplateArgs().empty()) { - err() << "Def '" << $3->getName() - << "' is not permitted to have template arguments!\n"; - exit(1); - } + assert($3->getTemplateArgs().empty() && "How'd this get template args?"); $$ = $3; }; From lattner at cs.uiuc.edu Thu Sep 29 23:43:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 23:43:08 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.cpp Message-ID: <200509300443.XAA16060@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.cpp updated: 1.6 -> 1.7 --- Log message: Regenerate --- Diffs of the changes: (+93 -97) FileParser.cpp | 182 +++++++++++++++++++++++++++++---------------------------- 1 files changed, 93 insertions(+), 89 deletions(-) Index: llvm/utils/TableGen/FileParser.cpp diff -u llvm/utils/TableGen/FileParser.cpp:1.6 llvm/utils/TableGen/FileParser.cpp:1.7 --- llvm/utils/TableGen/FileParser.cpp:1.6 Thu Sep 29 23:11:27 2005 +++ llvm/utils/TableGen/FileParser.cpp Thu Sep 29 23:42:56 2005 @@ -276,7 +276,7 @@ 133, 135, 136, 140, 141, 143, 145, 149, 154, 157, 164, 165, 168, 170, 174, 176, 181, 183, 187, 188, 191, 193, 197, 201, 202, 204, 206, 207, 209, 211, - 213, 214, 219, 223, 227, 229, 231, 236, 238, 242, + 213, 214, 218, 223, 227, 229, 231, 236, 238, 242, 243, 248, 253, 256, 258, 261 }; @@ -302,7 +302,7 @@ 55, 0, 56, 34, 55, 0, 0, 35, 56, 0, 51, 0, 58, 34, 51, 0, 23, 58, 24, 0, 0, 59, 0, 19, 0, 0, 61, 0, 62, 0, - 62, 0, 0, 60, 57, 66, 54, 0, 10, 63, + 62, 0, 0, 57, 66, 54, 0, 10, 63, 60, 65, 0, 11, 64, 65, 0, 67, 0, 68, 0, 19, 48, 25, 42, 0, 70, 0, 71, 34, 70, 0, 0, 13, 73, 71, 14, 0, 72, 27, 74, @@ -321,8 +321,8 @@ 460, 462, 462, 466, 468, 472, 475, 479, 489, 491, 497, 497, 498, 498, 500, 502, 506, 511, 516, 519, 523, 526, 531, 532, 532, 534, 534, 536, 545, 553, - 562, 577, 582, 586, 599, 599, 601, 606, 606, 609, - 609, 612, 615, 619, 619, 621 + 562, 577, 582, 586, 595, 595, 597, 602, 602, 605, + 605, 608, 611, 615, 615, 617 }; #endif @@ -362,102 +362,102 @@ 1, 0, 3, 0, 1, 1, 3, 4, 2, 6, 0, 2, 1, 3, 1, 4, 1, 3, 0, 2, 1, 3, 3, 0, 1, 1, 0, 1, 1, 1, - 0, 4, 3, 3, 1, 1, 4, 1, 3, 0, + 0, 3, 4, 3, 1, 1, 4, 1, 3, 0, 4, 4, 2, 1, 2, 1 }; static const short yydefact[] = { 0, 67, 67, 80, 75, 76, 84, 0, 86, 66, 68, - 69, 64, 70, 64, 0, 0, 83, 85, 10, 65, - 59, 73, 74, 42, 78, 0, 0, 11, 0, 61, - 0, 0, 71, 0, 0, 81, 0, 82, 5, 3, - 2, 0, 0, 7, 8, 1, 9, 0, 63, 10, - 55, 57, 60, 0, 35, 41, 0, 0, 79, 0, - 0, 12, 62, 0, 0, 51, 53, 72, 37, 0, - 0, 43, 0, 0, 0, 14, 20, 15, 16, 17, - 44, 44, 0, 77, 0, 0, 0, 48, 46, 0, - 58, 10, 36, 38, 0, 0, 0, 0, 0, 45, - 0, 33, 0, 0, 0, 4, 6, 13, 56, 0, - 0, 54, 0, 52, 40, 0, 0, 0, 0, 0, - 18, 22, 29, 34, 0, 0, 0, 23, 47, 42, - 49, 39, 0, 0, 0, 19, 0, 31, 0, 24, - 21, 25, 0, 0, 0, 0, 30, 29, 0, 26, + 69, 64, 70, 59, 0, 0, 83, 85, 10, 65, + 59, 0, 71, 74, 42, 78, 0, 0, 11, 0, + 61, 0, 73, 1, 55, 57, 60, 0, 0, 0, + 81, 0, 82, 5, 3, 2, 0, 0, 7, 8, + 9, 0, 63, 10, 0, 0, 51, 53, 72, 35, + 41, 0, 0, 79, 0, 0, 12, 62, 0, 0, + 0, 14, 20, 15, 16, 17, 44, 44, 0, 46, + 0, 58, 10, 37, 0, 0, 43, 77, 0, 0, + 0, 48, 0, 0, 0, 0, 0, 45, 0, 33, + 0, 0, 0, 56, 0, 0, 54, 0, 52, 36, + 38, 4, 6, 13, 0, 0, 0, 0, 18, 22, + 29, 34, 0, 0, 0, 23, 47, 42, 49, 40, + 0, 0, 0, 0, 19, 0, 31, 0, 24, 21, + 25, 0, 39, 0, 0, 0, 30, 29, 0, 26, 27, 28, 32, 0, 50, 0, 0, 0 }; -static const short yydefgoto[] = { 47, - 48, 29, 88, 89, 138, 124, 125, 56, 57, 35, - 99, 100, 30, 114, 92, 68, 52, 53, 33, 31, - 20, 21, 10, 11, 12, 14, 22, 54, 4, 5, - 6, 25, 26, 7, 15, 8, 156 +static const short yydefgoto[] = { 35, + 52, 30, 92, 80, 137, 122, 123, 61, 62, 40, + 97, 98, 31, 109, 83, 59, 36, 37, 23, 32, + 20, 21, 10, 11, 12, 14, 24, 38, 4, 5, + 6, 26, 27, 7, 15, 8, 156 }; -static const short yypact[] = { 52, - 15, 15,-32768,-32768,-32768,-32768, 3, 52,-32768,-32768, --32768, 4,-32768, 4, 22, 52,-32768,-32768, 34,-32768, - -20,-32768,-32768, 28,-32768, -9, -2,-32768, 63,-32768, - -3, 37,-32768, 39, 35,-32768, 22,-32768,-32768,-32768, --32768, 50, 51,-32768,-32768,-32768,-32768, 59,-32768, 34, - 66,-32768, 45, -15, -12, 46, 62, 32,-32768, 102, - 63, 75,-32768, 32, 37,-32768,-32768,-32768,-32768, 104, - 106,-32768, 93, 94, 95,-32768, 105,-32768,-32768,-32768, - 32, 32, 110, 77, 107, 108, 32,-32768, 77, 8, --32768, 5,-32768, -8, 32, 32, 32, 32, 109, 96, - 103, 32, 39, 39, 115,-32768,-32768, 77,-32768, 32, - 116,-32768, 99,-32768,-32768, 120, 67, 68, 76, 11, --32768,-32768, 57, 111, 113, 112, 114,-32768, 77, 28, --32768,-32768, 32, 32, 32,-32768, 119,-32768, 32,-32768, --32768,-32768, 117, 82, 85, 90,-32768, 57, 32,-32768, --32768,-32768,-32768, 56,-32768, 141, 143,-32768 +static const short yypact[] = { 2, + 0, 0,-32768,-32768,-32768,-32768, 7, 2,-32768,-32768, +-32768, 17,-32768, -19, 33, 2,-32768,-32768, 41,-32768, + -19, 35,-32768,-32768, 14,-32768, -13, -3,-32768, 59, +-32768, -10,-32768,-32768, 34,-32768, 26, 22, 62, 54, +-32768, 33,-32768,-32768,-32768,-32768, 58, 66,-32768,-32768, +-32768, 65,-32768, 41, 29, 35,-32768,-32768,-32768, -9, + 51, 72, 29,-32768, 84, 59, 69,-32768, 74, 94, + 95,-32768, 102,-32768,-32768,-32768, 29, 29, 89, 93, + 49,-32768, 10,-32768, 110, 111,-32768, 93, 106, 107, + 29,-32768, 29, 29, 29, 29, 104, 99, 105, 29, + 62, 62, 115,-32768, 29, 117,-32768, 100,-32768,-32768, + -7,-32768,-32768, 93, 64, 70, 76, 53,-32768,-32768, + 61, 108, 112, 113, 109,-32768, 93, 14,-32768,-32768, + 120, 29, 29, 29,-32768, 123,-32768, 29,-32768,-32768, +-32768, 119,-32768, 82, 85, 90,-32768, 61, 29,-32768, +-32768,-32768,-32768, 45,-32768, 140, 146,-32768 }; -static const short yypgoto[] = { -25, - 86,-32768,-32768, -58, 0,-32768,-32768,-32768, -84, 19, - 69, -62, -49,-32768,-32768,-32768, 87,-32768,-32768,-32768, --32768,-32768,-32768, 148,-32768,-32768, 139,-32768,-32768,-32768, - -4, 118,-32768,-32768,-32768, 138,-32768 +static const short yypgoto[] = { -27, + 81,-32768,-32768, -63, 1,-32768,-32768,-32768, -66, 20, + 73, -53, -50,-32768,-32768,-32768, 96,-32768,-32768,-32768, +-32768,-32768,-32768, 148,-32768,-32768, 132,-32768,-32768,-32768, + -2, 114,-32768,-32768,-32768, 138,-32768 }; -#define YYLAST 155 +#define YYLAST 156 -static const short yytable[] = { 84, - 63, 90, 17, 18, 36, 69, 51, 1, 2, 115, - 3, 66, 1, 2, 32, 3, 28, 111, 126, 127, - 49, 67, 18, 70, 37, 38, 19, 116, 108, 16, - 50, 109, 112, 9, 136, 120, 117, 118, 119, 51, - 24, 110, 113, 123, 110, 28, 73, 74, 75, 76, - 77, 129, 78, 79, 34, 46, 55, 80, 81, 58, - 82, 1, 2, 83, 3, 39, 40, 41, 42, 43, - 44, 45, 60, 61, 144, 145, 146, 62, 65, 71, - 148, 46, 103, 103, 104, 104, 105, 105, 64, 72, - 154, 137, 155, 103, 103, 104, 104, 105, 105, 87, - 133, 134, 103, 103, 104, 104, 105, 105, 103, 135, - 104, 103, 105, 104, 150, 105, 103, 151, 104, 85, - 105, 93, 152, 94, 95, 96, 97, 98, 102, 110, - 106, 107, 122, 128, 130, 131, 121, 132, 147, 141, - 157, 149, 158, 142, 139, 140, 86, 153, 143, 13, - 101, 91, 23, 27, 59 +static const short yytable[] = { 88, + 41, 81, 51, 68, 17, 18, 1, 2, 84, 3, + 130, 1, 2, 53, 3, 22, 1, 2, 9, 3, + 42, 29, 106, 54, 43, 18, 85, 114, 131, 115, + 116, 117, 108, 16, 124, 125, 121, 107, 51, 19, + 39, 127, 118, 69, 70, 71, 72, 73, 57, 74, + 75, 25, 29, 34, 76, 77, 55, 78, 58, 56, + 79, 44, 45, 46, 47, 48, 49, 50, 144, 145, + 146, 101, 104, 102, 148, 103, 135, 34, 63, 60, + 65, 155, 105, 67, 86, 154, 105, 101, 66, 102, + 101, 103, 102, 91, 103, 136, 101, 132, 102, 87, + 103, 89, 101, 133, 102, 93, 103, 100, 101, 134, + 102, 101, 103, 102, 150, 103, 101, 151, 102, 101, + 103, 102, 152, 103, 96, 94, 95, 110, 111, 112, + 113, 119, 105, 126, 120, 128, 129, 143, 141, 157, + 140, 138, 147, 149, 139, 158, 90, 142, 153, 13, + 99, 82, 33, 28, 0, 64 }; -static const short yycheck[] = { 58, - 50, 64, 7, 8, 14, 18, 32, 10, 11, 18, - 13, 27, 10, 11, 35, 13, 12, 13, 103, 104, - 24, 37, 27, 36, 34, 28, 23, 36, 87, 27, - 34, 24, 28, 19, 24, 98, 95, 96, 97, 65, - 19, 34, 92, 102, 34, 12, 15, 16, 17, 18, - 19, 110, 21, 22, 27, 19, 18, 26, 27, 25, - 29, 10, 11, 32, 13, 3, 4, 5, 6, 7, - 8, 9, 23, 23, 133, 134, 135, 19, 34, 34, - 139, 19, 27, 27, 29, 29, 31, 31, 23, 28, - 149, 35, 37, 27, 27, 29, 29, 31, 31, 25, - 34, 34, 27, 27, 29, 29, 31, 31, 27, 34, - 29, 27, 31, 29, 33, 31, 27, 33, 29, 18, - 31, 18, 33, 18, 32, 32, 32, 23, 19, 34, - 24, 24, 30, 19, 19, 37, 28, 18, 20, 28, - 0, 25, 0, 30, 34, 33, 61, 148, 130, 2, - 82, 65, 14, 16, 37 +static const short yycheck[] = { 63, + 14, 55, 30, 54, 7, 8, 10, 11, 18, 13, + 18, 10, 11, 24, 13, 35, 10, 11, 19, 13, + 34, 12, 13, 34, 28, 28, 36, 91, 36, 93, + 94, 95, 83, 27, 101, 102, 100, 28, 66, 23, + 27, 105, 96, 15, 16, 17, 18, 19, 27, 21, + 22, 19, 12, 19, 26, 27, 23, 29, 37, 34, + 32, 3, 4, 5, 6, 7, 8, 9, 132, 133, + 134, 27, 24, 29, 138, 31, 24, 19, 25, 18, + 23, 37, 34, 19, 34, 149, 34, 27, 23, 29, + 27, 31, 29, 25, 31, 35, 27, 34, 29, 28, + 31, 18, 27, 34, 29, 32, 31, 19, 27, 34, + 29, 27, 31, 29, 33, 31, 27, 33, 29, 27, + 31, 29, 33, 31, 23, 32, 32, 18, 18, 24, + 24, 28, 34, 19, 30, 19, 37, 18, 30, 0, + 28, 34, 20, 25, 33, 0, 66, 128, 148, 2, + 78, 56, 21, 16, -1, 42 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/usr/share/bison.simple" @@ -1545,7 +1545,7 @@ delete (*yyvsp[0].SubClassList)[i].second; } delete yyvsp[0].SubClassList; // Delete the class list... - + // Process any variables on the set stack... for (unsigned i = 0, e = LetStack.size(); i != e; ++i) for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) @@ -1564,8 +1564,8 @@ case 73: #line 582 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { - yyval.Rec = yyvsp[0].Rec; -; + yyval.Rec = yyvsp[0].Rec; + ; break;} case 74: #line 586 "/Users/sabre/llvm/utils/TableGen/FileParser.y" @@ -1573,47 +1573,43 @@ yyvsp[0].Rec->resolveReferences(); // If ObjectBody has template arguments, it's an error. - if (!yyvsp[0].Rec->getTemplateArgs().empty()) { - err() << "Def '" << yyvsp[0].Rec->getName() - << "' is not permitted to have template arguments!\n"; - exit(1); - } + assert(yyvsp[0].Rec->getTemplateArgs().empty() && "How'd this get template args?"); yyval.Rec = yyvsp[0].Rec; ; break;} case 77: -#line 601 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 597 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { LetStack.back().push_back(LetRecord(*yyvsp[-3].StrVal, yyvsp[-2].BitList, yyvsp[0].Initializer)); delete yyvsp[-3].StrVal; delete yyvsp[-2].BitList; ; break;} case 80: -#line 609 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 605 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { LetStack.push_back(std::vector()); ; break;} case 82: -#line 612 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 608 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { LetStack.pop_back(); ; break;} case 83: -#line 615 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 611 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { LetStack.pop_back(); ; break;} case 84: -#line 619 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 615 "/Users/sabre/llvm/utils/TableGen/FileParser.y" {; break;} case 85: -#line 619 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 615 "/Users/sabre/llvm/utils/TableGen/FileParser.y" {; break;} case 86: -#line 621 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 617 "/Users/sabre/llvm/utils/TableGen/FileParser.y" {; break;} } @@ -1838,7 +1834,7 @@ } return 1; } -#line 623 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 619 "/Users/sabre/llvm/utils/TableGen/FileParser.y" int yyerror(const char *ErrorMsg) { From lattner at cs.uiuc.edu Thu Sep 29 23:52:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 23:52:55 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/TableGen/ForwardRef.td Message-ID: <200509300452.XAA16384@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/TableGen: ForwardRef.td updated: 1.1 -> 1.2 --- Log message: Add a test that you can forward ref a class. --- Diffs of the changes: (+9 -0) ForwardRef.td | 9 +++++++++ 1 files changed, 9 insertions(+) Index: llvm/test/Regression/TableGen/ForwardRef.td diff -u llvm/test/Regression/TableGen/ForwardRef.td:1.1 llvm/test/Regression/TableGen/ForwardRef.td:1.2 --- llvm/test/Regression/TableGen/ForwardRef.td:1.1 Thu Sep 29 23:10:17 2005 +++ llvm/test/Regression/TableGen/ForwardRef.td Thu Sep 29 23:52:43 2005 @@ -4,3 +4,12 @@ list x; } +class foo; +class foo; + +class baz { list y; } + +class foo { + +} + From lattner at cs.uiuc.edu Thu Sep 29 23:53:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 23:53:16 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.y Message-ID: <200509300453.XAA16404@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.y updated: 1.38 -> 1.39 --- Log message: Refactor this a bit to move ParsingTemplateArgs to only apply to classes, not defs. Implement support for forward definitions of classes. This implements TableGen/ForwardRef.td. --- Diffs of the changes: (+25 -11) FileParser.y | 36 +++++++++++++++++++++++++----------- 1 files changed, 25 insertions(+), 11 deletions(-) Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.38 llvm/utils/TableGen/FileParser.y:1.39 --- llvm/utils/TableGen/FileParser.y:1.38 Thu Sep 29 23:42:31 2005 +++ llvm/utils/TableGen/FileParser.y Thu Sep 29 23:53:04 2005 @@ -214,7 +214,7 @@ %type DagArgList DagArgListNE %type ValueList ValueListNE %type BitList OptBitList RBitList -%type Declaration OptID OptVarName +%type Declaration OptID OptVarName ObjectName %start File @@ -537,20 +537,31 @@ static unsigned AnonCounter = 0; if ($1->empty()) *$1 = "anonymous."+utostr(AnonCounter++); - CurRec = new Record(*$1); - delete $1; - ParsingTemplateArgs = true; + $$ = $1; }; ClassName : ObjectName { - if (Records.getClass(CurRec->getName())) { - err() << "Class '" << CurRec->getName() << "' already defined!\n"; - exit(1); + // If a class of this name already exists, it must be a forward ref. + if ((CurRec = Records.getClass(*$1))) { + // If the body was previously defined, this is an error. + if (!CurRec->getValues().empty() || + !CurRec->getSuperClasses().empty() || + !CurRec->getTemplateArgs().empty()) { + err() << "Class '" << CurRec->getName() << "' already defined!\n"; + exit(1); + } + } else { + // If this is the first reference to this class, create and add it. + CurRec = new Record(*$1); + Records.addClass(CurRec); } - Records.addClass(CurRec); + delete $1; }; DefName : ObjectName { + CurRec = new Record(*$1); + delete $1; + // Ensure redefinition doesn't happen. if (Records.getDef(CurRec->getName())) { err() << "Def '" << CurRec->getName() << "' already defined!\n"; @@ -560,7 +571,6 @@ }; ObjectBody : ClassList { - ParsingTemplateArgs = false; for (unsigned i = 0, e = $1->size(); i != e; ++i) { addSubClass((*$1)[i].first, *(*$1)[i].second); // Delete the template arg values for the class @@ -579,8 +589,12 @@ CurRec = 0; }; -ClassInst : CLASS ClassName OptTemplateArgList ObjectBody { - $$ = $4; +ClassInst : CLASS ClassName { + ParsingTemplateArgs = true; + } OptTemplateArgList { + ParsingTemplateArgs = false; + } ObjectBody { + $$ = $6; }; DefInst : DEF DefName ObjectBody { From lattner at cs.uiuc.edu Thu Sep 29 23:53:36 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 29 Sep 2005 23:53:36 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.cpp Message-ID: <200509300453.XAA16439@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.cpp updated: 1.7 -> 1.8 --- Log message: Regenerate --- Diffs of the changes: (+151 -127) FileParser.cpp | 271 +++++++++++++++++++++++++++++++-------------------------- 1 files changed, 151 insertions(+), 120 deletions(-) Index: llvm/utils/TableGen/FileParser.cpp diff -u llvm/utils/TableGen/FileParser.cpp:1.7 llvm/utils/TableGen/FileParser.cpp:1.8 --- llvm/utils/TableGen/FileParser.cpp:1.7 Thu Sep 29 23:42:56 2005 +++ llvm/utils/TableGen/FileParser.cpp Thu Sep 29 23:53:25 2005 @@ -230,11 +230,11 @@ -#define YYFINAL 158 +#define YYFINAL 160 #define YYFLAG -32768 #define YYNTBASE 38 -#define YYTRANSLATE(x) ((unsigned)(x) <= 276 ? yytranslate[x] : 76) +#define YYTRANSLATE(x) ((unsigned)(x) <= 276 ? yytranslate[x] : 78) static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -276,8 +276,8 @@ 133, 135, 136, 140, 141, 143, 145, 149, 154, 157, 164, 165, 168, 170, 174, 176, 181, 183, 187, 188, 191, 193, 197, 201, 202, 204, 206, 207, 209, 211, - 213, 214, 218, 223, 227, 229, 231, 236, 238, 242, - 243, 248, 253, 256, 258, 261 + 213, 214, 218, 219, 220, 227, 231, 233, 235, 240, + 242, 246, 247, 252, 257, 260, 262, 265 }; static const short yyrhs[] = { 19, @@ -302,12 +302,12 @@ 55, 0, 56, 34, 55, 0, 0, 35, 56, 0, 51, 0, 58, 34, 51, 0, 23, 58, 24, 0, 0, 59, 0, 19, 0, 0, 61, 0, 62, 0, - 62, 0, 0, 57, 66, 54, 0, 10, 63, 60, - 65, 0, 11, 64, 65, 0, 67, 0, 68, 0, - 19, 48, 25, 42, 0, 70, 0, 71, 34, 70, - 0, 0, 13, 73, 71, 14, 0, 72, 27, 74, - 28, 0, 72, 69, 0, 69, 0, 74, 69, 0, - 74, 0 + 62, 0, 0, 57, 66, 54, 0, 0, 0, 10, + 63, 68, 60, 69, 65, 0, 11, 64, 65, 0, + 67, 0, 70, 0, 19, 48, 25, 42, 0, 72, + 0, 73, 34, 72, 0, 0, 13, 75, 73, 14, + 0, 74, 27, 76, 28, 0, 74, 71, 0, 71, + 0, 76, 71, 0, 76, 0 }; #endif @@ -320,9 +320,9 @@ 382, 387, 393, 396, 399, 402, 415, 429, 431, 444, 460, 462, 462, 466, 468, 472, 475, 479, 489, 491, 497, 497, 498, 498, 500, 502, 506, 511, 516, 519, - 523, 526, 531, 532, 532, 534, 534, 536, 545, 553, - 562, 577, 582, 586, 595, 595, 597, 602, 602, 605, - 605, 608, 611, 615, 615, 617 + 523, 526, 531, 532, 532, 534, 534, 536, 543, 561, + 573, 587, 592, 594, 596, 600, 609, 609, 611, 616, + 616, 619, 619, 622, 625, 629, 629, 631 }; #endif @@ -337,8 +337,8 @@ "DagArgList","RBitList","BitList","OptBitList","ValueList","ValueListNE","Declaration", "BodyItem","BodyList","Body","SubClassRef","ClassListNE","ClassList","DeclListNE", "TemplateArgList","OptTemplateArgList","OptID","ObjectName","ClassName","DefName", -"ObjectBody","@1","ClassInst","DefInst","Object","LETItem","LETList","LETCommand", -"@2","ObjectList","File", NULL +"ObjectBody","@1","ClassInst","@2","@3","DefInst","Object","LETItem","LETList", +"LETCommand","@4","ObjectList","File", NULL }; #endif @@ -350,8 +350,8 @@ 47, 48, 48, 49, 49, 50, 50, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 60, 60, 61, 61, 62, 63, 64, - 66, 65, 67, 68, 69, 69, 70, 71, 71, 73, - 72, 69, 69, 74, 74, 75 + 66, 65, 68, 69, 67, 70, 71, 71, 72, 73, + 73, 75, 74, 71, 71, 76, 76, 77 }; static const short yyr2[] = { 0, @@ -362,102 +362,104 @@ 1, 0, 3, 0, 1, 1, 3, 4, 2, 6, 0, 2, 1, 3, 1, 4, 1, 3, 0, 2, 1, 3, 3, 0, 1, 1, 0, 1, 1, 1, - 0, 3, 4, 3, 1, 1, 4, 1, 3, 0, - 4, 4, 2, 1, 2, 1 + 0, 3, 0, 0, 6, 3, 1, 1, 4, 1, + 3, 0, 4, 4, 2, 1, 2, 1 }; static const short yydefact[] = { 0, - 67, 67, 80, 75, 76, 84, 0, 86, 66, 68, - 69, 64, 70, 59, 0, 0, 83, 85, 10, 65, - 59, 0, 71, 74, 42, 78, 0, 0, 11, 0, - 61, 0, 73, 1, 55, 57, 60, 0, 0, 0, - 81, 0, 82, 5, 3, 2, 0, 0, 7, 8, - 9, 0, 63, 10, 0, 0, 51, 53, 72, 35, - 41, 0, 0, 79, 0, 0, 12, 62, 0, 0, - 0, 14, 20, 15, 16, 17, 44, 44, 0, 46, - 0, 58, 10, 37, 0, 0, 43, 77, 0, 0, - 0, 48, 0, 0, 0, 0, 0, 45, 0, 33, - 0, 0, 0, 56, 0, 0, 54, 0, 52, 36, - 38, 4, 6, 13, 0, 0, 0, 0, 18, 22, - 29, 34, 0, 0, 0, 23, 47, 42, 49, 40, - 0, 0, 0, 0, 19, 0, 31, 0, 24, 21, - 25, 0, 39, 0, 0, 0, 30, 29, 0, 26, - 27, 28, 32, 0, 50, 0, 0, 0 + 67, 67, 82, 77, 78, 86, 0, 88, 66, 68, + 69, 73, 70, 59, 0, 0, 85, 87, 64, 0, + 71, 76, 42, 80, 0, 0, 10, 65, 74, 1, + 55, 57, 60, 0, 0, 0, 83, 0, 84, 11, + 0, 61, 0, 59, 0, 0, 51, 53, 72, 35, + 41, 0, 0, 81, 5, 3, 2, 0, 0, 7, + 8, 9, 0, 63, 10, 75, 0, 0, 0, 14, + 20, 15, 16, 17, 44, 44, 0, 46, 0, 58, + 10, 37, 0, 0, 43, 79, 0, 0, 12, 62, + 0, 0, 0, 0, 0, 45, 0, 33, 0, 0, + 0, 56, 0, 0, 54, 0, 52, 36, 38, 0, + 0, 0, 48, 0, 0, 0, 0, 18, 22, 29, + 34, 0, 0, 0, 23, 47, 42, 49, 40, 0, + 4, 6, 13, 0, 0, 0, 19, 0, 31, 0, + 24, 21, 25, 0, 39, 0, 0, 0, 30, 29, + 0, 26, 27, 28, 32, 0, 50, 0, 0, 0 }; -static const short yydefgoto[] = { 35, - 52, 30, 92, 80, 137, 122, 123, 61, 62, 40, - 97, 98, 31, 109, 83, 59, 36, 37, 23, 32, - 20, 21, 10, 11, 12, 14, 24, 38, 4, 5, - 6, 26, 27, 7, 15, 8, 156 +static const short yydefgoto[] = { 31, + 63, 41, 113, 78, 139, 121, 122, 51, 52, 36, + 95, 96, 42, 107, 81, 49, 32, 33, 21, 43, + 28, 29, 10, 11, 12, 14, 22, 34, 4, 19, + 44, 5, 6, 24, 25, 7, 15, 8, 158 }; -static const short yypact[] = { 2, - 0, 0,-32768,-32768,-32768,-32768, 7, 2,-32768,-32768, --32768, 17,-32768, -19, 33, 2,-32768,-32768, 41,-32768, - -19, 35,-32768,-32768, 14,-32768, -13, -3,-32768, 59, --32768, -10,-32768,-32768, 34,-32768, 26, 22, 62, 54, --32768, 33,-32768,-32768,-32768,-32768, 58, 66,-32768,-32768, --32768, 65,-32768, 41, 29, 35,-32768,-32768,-32768, -9, - 51, 72, 29,-32768, 84, 59, 69,-32768, 74, 94, - 95,-32768, 102,-32768,-32768,-32768, 29, 29, 89, 93, - 49,-32768, 10,-32768, 110, 111,-32768, 93, 106, 107, - 29,-32768, 29, 29, 29, 29, 104, 99, 105, 29, - 62, 62, 115,-32768, 29, 117,-32768, 100,-32768,-32768, - -7,-32768,-32768, 93, 64, 70, 76, 53,-32768,-32768, - 61, 108, 112, 113, 109,-32768, 93, 14,-32768,-32768, - 120, 29, 29, 29,-32768, 123,-32768, 29,-32768,-32768, --32768, 119,-32768, 82, 85, 90,-32768, 61, 29,-32768, --32768,-32768,-32768, 45,-32768, 140, 146,-32768 +static const short yypact[] = { 56, + -4, -4,-32768,-32768,-32768,-32768, 1, 56,-32768,-32768, +-32768,-32768,-32768, 8, 2, 56,-32768,-32768, 23, 30, +-32768,-32768, 50,-32768, -11, -3, 66,-32768,-32768,-32768, + 62,-32768, 55, 34, 61, 68,-32768, 2,-32768,-32768, + 49,-32768, -8, 8, 15, 30,-32768,-32768,-32768, -14, + 82, 67, 15,-32768,-32768,-32768,-32768, 95, 97,-32768, +-32768,-32768, 77,-32768, 66,-32768, 89, 90, 91,-32768, + 101,-32768,-32768,-32768, 15, 15, 106, 73, 39,-32768, + 7,-32768, 108, 109,-32768, 73, 110, 49, 104,-32768, + 15, 15, 15, 15, 102, 98, 103, 15, 61, 61, + 112,-32768, 15, 115,-32768, 99,-32768,-32768, -9, 111, + 113, 15,-32768, 57, 63, 72, 41,-32768,-32768, 45, + 105, 107, 114, 116,-32768, 73, 50,-32768,-32768, 120, +-32768,-32768, 73, 15, 15, 15,-32768, 121,-32768, 15, +-32768,-32768,-32768, 118,-32768, 78, 81, 86,-32768, 45, + 15,-32768,-32768,-32768,-32768, 33,-32768, 144, 145,-32768 }; -static const short yypgoto[] = { -27, - 81,-32768,-32768, -63, 1,-32768,-32768,-32768, -66, 20, - 73, -53, -50,-32768,-32768,-32768, 96,-32768,-32768,-32768, --32768,-32768,-32768, 148,-32768,-32768, 132,-32768,-32768,-32768, - -2, 114,-32768,-32768,-32768, 138,-32768 +static const short yypgoto[] = { -40, + 59,-32768,-32768, -53, -1,-32768,-32768,-32768, -82, 21, + 74, -43, -52,-32768,-32768,-32768, 117,-32768,-32768,-32768, +-32768,-32768,-32768, 149,-32768,-32768, 122,-32768,-32768,-32768, +-32768,-32768, -2, 119,-32768,-32768,-32768, 136,-32768 }; -#define YYLAST 156 +#define YYLAST 166 -static const short yytable[] = { 88, - 41, 81, 51, 68, 17, 18, 1, 2, 84, 3, - 130, 1, 2, 53, 3, 22, 1, 2, 9, 3, - 42, 29, 106, 54, 43, 18, 85, 114, 131, 115, - 116, 117, 108, 16, 124, 125, 121, 107, 51, 19, - 39, 127, 118, 69, 70, 71, 72, 73, 57, 74, - 75, 25, 29, 34, 76, 77, 55, 78, 58, 56, - 79, 44, 45, 46, 47, 48, 49, 50, 144, 145, - 146, 101, 104, 102, 148, 103, 135, 34, 63, 60, - 65, 155, 105, 67, 86, 154, 105, 101, 66, 102, - 101, 103, 102, 91, 103, 136, 101, 132, 102, 87, - 103, 89, 101, 133, 102, 93, 103, 100, 101, 134, - 102, 101, 103, 102, 150, 103, 101, 151, 102, 101, - 103, 102, 152, 103, 96, 94, 95, 110, 111, 112, - 113, 119, 105, 126, 120, 128, 129, 143, 141, 157, - 140, 138, 147, 149, 139, 158, 90, 142, 153, 13, - 99, 82, 33, 28, 0, 64 +static const short yytable[] = { 86, + 62, 79, 37, 82, 17, 18, 1, 2, 129, 3, + 1, 2, 90, 3, 9, 64, 123, 124, 40, 104, + 23, 83, 38, 18, 39, 65, 130, 16, 106, 67, + 68, 69, 70, 71, 105, 72, 73, 114, 115, 116, + 74, 75, 20, 76, 120, 27, 77, 62, 30, 126, + 117, 55, 56, 57, 58, 59, 60, 61, 133, 99, + 47, 100, 102, 101, 137, 1, 2, 30, 3, 157, + 48, 99, 103, 100, 103, 101, 35, 40, 50, 138, + 146, 147, 148, 99, 45, 100, 150, 101, 46, 99, + 134, 100, 53, 101, 85, 89, 135, 156, 99, 99, + 100, 100, 101, 101, 99, 136, 100, 99, 101, 100, + 152, 101, 99, 153, 100, 84, 101, 87, 154, 88, + 91, 92, 93, 94, 98, 108, 109, 110, 112, 118, + 125, 103, 119, 127, 131, 128, 132, 145, 140, 141, + 149, 142, 151, 159, 160, 143, 111, 144, 155, 97, + 13, 26, 0, 0, 0, 0, 54, 0, 0, 0, + 0, 0, 80, 0, 0, 66 }; -static const short yycheck[] = { 63, - 14, 55, 30, 54, 7, 8, 10, 11, 18, 13, - 18, 10, 11, 24, 13, 35, 10, 11, 19, 13, - 34, 12, 13, 34, 28, 28, 36, 91, 36, 93, - 94, 95, 83, 27, 101, 102, 100, 28, 66, 23, - 27, 105, 96, 15, 16, 17, 18, 19, 27, 21, - 22, 19, 12, 19, 26, 27, 23, 29, 37, 34, - 32, 3, 4, 5, 6, 7, 8, 9, 132, 133, - 134, 27, 24, 29, 138, 31, 24, 19, 25, 18, - 23, 37, 34, 19, 34, 149, 34, 27, 23, 29, - 27, 31, 29, 25, 31, 35, 27, 34, 29, 28, - 31, 18, 27, 34, 29, 32, 31, 19, 27, 34, - 29, 27, 31, 29, 33, 31, 27, 33, 29, 27, - 31, 29, 33, 31, 23, 32, 32, 18, 18, 24, - 24, 28, 34, 19, 30, 19, 37, 18, 30, 0, - 28, 34, 20, 25, 33, 0, 66, 128, 148, 2, - 78, 56, 21, 16, -1, 42 +static const short yycheck[] = { 53, + 41, 45, 14, 18, 7, 8, 10, 11, 18, 13, + 10, 11, 65, 13, 19, 24, 99, 100, 12, 13, + 19, 36, 34, 26, 28, 34, 36, 27, 81, 15, + 16, 17, 18, 19, 28, 21, 22, 91, 92, 93, + 26, 27, 35, 29, 98, 23, 32, 88, 19, 103, + 94, 3, 4, 5, 6, 7, 8, 9, 112, 27, + 27, 29, 24, 31, 24, 10, 11, 19, 13, 37, + 37, 27, 34, 29, 34, 31, 27, 12, 18, 35, + 134, 135, 136, 27, 23, 29, 140, 31, 34, 27, + 34, 29, 25, 31, 28, 19, 34, 151, 27, 27, + 29, 29, 31, 31, 27, 34, 29, 27, 31, 29, + 33, 31, 27, 33, 29, 34, 31, 23, 33, 23, + 32, 32, 32, 23, 19, 18, 18, 18, 25, 28, + 19, 34, 30, 19, 24, 37, 24, 18, 34, 33, + 20, 28, 25, 0, 0, 30, 88, 127, 150, 76, + 2, 16, -1, -1, -1, -1, 38, -1, -1, -1, + -1, -1, 46, -1, -1, 44 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/usr/share/bison.simple" @@ -1509,24 +1511,35 @@ static unsigned AnonCounter = 0; if (yyvsp[0].StrVal->empty()) *yyvsp[0].StrVal = "anonymous."+utostr(AnonCounter++); - CurRec = new Record(*yyvsp[0].StrVal); - delete yyvsp[0].StrVal; - ParsingTemplateArgs = true; + yyval.StrVal = yyvsp[0].StrVal; ; break;} case 69: -#line 545 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 543 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { - if (Records.getClass(CurRec->getName())) { - err() << "Class '" << CurRec->getName() << "' already defined!\n"; - exit(1); + // If a class of this name already exists, it must be a forward ref. + if (CurRec = Records.getClass(*yyvsp[0].StrVal)) { + // If the body was previously defined, this is an error. + if (!CurRec->getValues().empty() || + !CurRec->getSuperClasses().empty() || + !CurRec->getTemplateArgs().empty()) { + err() << "Class '" << CurRec->getName() << "' already defined!\n"; + exit(1); + } + } else { + // If this is the first reference to this class, create and add it. + CurRec = new Record(*yyvsp[0].StrVal); + Records.addClass(CurRec); } - Records.addClass(CurRec); + delete yyvsp[0].StrVal; ; break;} case 70: -#line 553 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 561 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { + CurRec = new Record(*yyvsp[0].StrVal); + delete yyvsp[0].StrVal; + // Ensure redefinition doesn't happen. if (Records.getDef(CurRec->getName())) { err() << "Def '" << CurRec->getName() << "' already defined!\n"; @@ -1536,9 +1549,8 @@ ; break;} case 71: -#line 562 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 573 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { - ParsingTemplateArgs = false; for (unsigned i = 0, e = yyvsp[0].SubClassList->size(); i != e; ++i) { addSubClass((*yyvsp[0].SubClassList)[i].first, *(*yyvsp[0].SubClassList)[i].second); // Delete the template arg values for the class @@ -1555,20 +1567,32 @@ ; break;} case 72: -#line 577 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 587 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { yyval.Rec = CurRec; CurRec = 0; ; break;} case 73: -#line 582 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 592 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ + ParsingTemplateArgs = true; + ; + break;} +case 74: +#line 594 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +{ + ParsingTemplateArgs = false; + ; + break;} +case 75: +#line 596 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { yyval.Rec = yyvsp[0].Rec; ; break;} -case 74: -#line 586 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +case 76: +#line 600 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { yyvsp[0].Rec->resolveReferences(); @@ -1577,39 +1601,39 @@ yyval.Rec = yyvsp[0].Rec; ; break;} -case 77: -#line 597 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +case 79: +#line 611 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { LetStack.back().push_back(LetRecord(*yyvsp[-3].StrVal, yyvsp[-2].BitList, yyvsp[0].Initializer)); delete yyvsp[-3].StrVal; delete yyvsp[-2].BitList; ; break;} -case 80: -#line 605 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +case 82: +#line 619 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { LetStack.push_back(std::vector()); ; break;} -case 82: -#line 608 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +case 84: +#line 622 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { LetStack.pop_back(); ; break;} -case 83: -#line 611 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +case 85: +#line 625 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { LetStack.pop_back(); ; break;} -case 84: -#line 615 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +case 86: +#line 629 "/Users/sabre/llvm/utils/TableGen/FileParser.y" {; break;} -case 85: -#line 615 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +case 87: +#line 629 "/Users/sabre/llvm/utils/TableGen/FileParser.y" {; break;} -case 86: -#line 617 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +case 88: +#line 631 "/Users/sabre/llvm/utils/TableGen/FileParser.y" {; break;} } @@ -1834,7 +1858,7 @@ } return 1; } -#line 619 "/Users/sabre/llvm/utils/TableGen/FileParser.y" +#line 633 "/Users/sabre/llvm/utils/TableGen/FileParser.y" int yyerror(const char *ErrorMsg) { From lattner at cs.uiuc.edu Fri Sep 30 01:10:02 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 01:10:02 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.cpp Message-ID: <200509300610.BAA18602@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.cpp updated: 1.8 -> 1.9 --- Log message: Fix a warning --- Diffs of the changes: (+1 -1) FileParser.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/FileParser.cpp diff -u llvm/utils/TableGen/FileParser.cpp:1.8 llvm/utils/TableGen/FileParser.cpp:1.9 --- llvm/utils/TableGen/FileParser.cpp:1.8 Thu Sep 29 23:53:25 2005 +++ llvm/utils/TableGen/FileParser.cpp Fri Sep 30 01:09:50 2005 @@ -1518,7 +1518,7 @@ #line 543 "/Users/sabre/llvm/utils/TableGen/FileParser.y" { // If a class of this name already exists, it must be a forward ref. - if (CurRec = Records.getClass(*yyvsp[0].StrVal)) { + if ((CurRec = Records.getClass(*yyvsp[0].StrVal))) { // If the body was previously defined, this is an error. if (!CurRec->getValues().empty() || !CurRec->getSuperClasses().empty() || From lattner at cs.uiuc.edu Fri Sep 30 01:42:35 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 01:42:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64.td Message-ID: <200509300642.BAA19505@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64.td updated: 1.2 -> 1.3 --- Log message: these registers don't belong to any register classes, so don't mark them as callee save. They can never be generated by the compiler. --- Diffs of the changes: (+21 -11) IA64.td | 32 +++++++++++++++++++++----------- 1 files changed, 21 insertions(+), 11 deletions(-) Index: llvm/lib/Target/IA64/IA64.td diff -u llvm/lib/Target/IA64/IA64.td:1.2 llvm/lib/Target/IA64/IA64.td:1.3 --- llvm/lib/Target/IA64/IA64.td:1.2 Wed Apr 6 01:18:36 2005 +++ llvm/lib/Target/IA64/IA64.td Fri Sep 30 01:42:24 2005 @@ -38,7 +38,10 @@ //'preserved' GRs: - [r4, r5, r6, r7, + [ + // We never generate references to these regs, so we don't need to declare + // that they are saved. In fact, we could just remove them entirely. + //r4, r5, r6, r7, //'special' GRs: @@ -67,19 +70,26 @@ */ //'preserved' FP regs: - F2,F3,F4,F5, - F16,F17,F18,F19,F20,F21,F22,F23, - F24,F25,F26,F27,F28,F29,F30,F31, + /* We never generate references to these regs, so we don't need to declare + * that they are saved. In fact, we could just remove them entirely. + * F2,F3,F4, F5, + * F16,F17,F18,F19,F20,F21,F22,F23, + * F24,F25,F26,F27,F28,F29,F30,F31, + */ //'preserved' predicate regs: - p1, p2, p3, p4, p5, - p16, p17, p18, p19, p20, p21, p22, p23, - p24, p25, p26, p27, p28, p29, p30, p31, - p32, p33, p34, p35, p36, p37, p38, p39, - p40, p41, p42, p43, p44, p45, p46, p47, - p48, p49, p50, p51, p52, p53, p54, p55, - p56, p57, p58, p59, p60, p61, p62, p63]; + /* We never generate references to these regs, so we don't need to declare + that they are saved. In fact, we could just remove them entirely. + p1, p2, p3, p4, p5, + p16, p17, p18, p19, p20, p21, p22, p23, + p24, p25, p26, p27, p28, p29, p30, p31, + p32, p33, p34, p35, p36, p37, p38, p39, + p40, p41, p42, p43, p44, p45, p46, p47, + p48, p49, p50, p51, p52, p53, p54, p55, + p56, p57, p58, p59, p60, p61, p62, p63 + */ + ]; // We don't go anywhere near the LP32 variant of IA64 as // sometimes seen in (for example) HP-UX From lattner at cs.uiuc.edu Fri Sep 30 01:44:10 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 01:44:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Skeleton/Skeleton.td SkeletonRegisterInfo.td Message-ID: <200509300644.BAA19619@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Skeleton: Skeleton.td updated: 1.2 -> 1.3 SkeletonRegisterInfo.td updated: 1.4 -> 1.5 --- Log message: CR registers are not used by this "target" --- Diffs of the changes: (+1 -8) Skeleton.td | 2 +- SkeletonRegisterInfo.td | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) Index: llvm/lib/Target/Skeleton/Skeleton.td diff -u llvm/lib/Target/Skeleton/Skeleton.td:1.2 llvm/lib/Target/Skeleton/Skeleton.td:1.3 --- llvm/lib/Target/Skeleton/Skeleton.td:1.2 Fri Jul 16 02:11:08 2004 +++ llvm/lib/Target/Skeleton/Skeleton.td Fri Sep 30 01:43:58 2005 @@ -33,7 +33,7 @@ let CalleeSavedRegisters = [R1, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, - F30, F31, CR2, CR3, CR4]; + F30, F31]; // Pull in Instruction Info: let InstructionSet = SkeletonInstrInfo; Index: llvm/lib/Target/Skeleton/SkeletonRegisterInfo.td diff -u llvm/lib/Target/Skeleton/SkeletonRegisterInfo.td:1.4 llvm/lib/Target/Skeleton/SkeletonRegisterInfo.td:1.5 --- llvm/lib/Target/Skeleton/SkeletonRegisterInfo.td:1.4 Fri Aug 19 13:53:43 2005 +++ llvm/lib/Target/Skeleton/SkeletonRegisterInfo.td Fri Sep 30 01:43:58 2005 @@ -75,13 +75,6 @@ def F28 : FPR<28, "F28">; def F29 : FPR<29, "F29">; def F30 : FPR<30, "F30">; def F31 : FPR<31, "F31">; - -// Condition registers -def CR0 : CR<0, "CR0">; def CR1 : CR<1, "CR1">; -def CR2 : CR<2, "CR2">; def CR3 : CR<3, "CR3">; -def CR4 : CR<4, "CR4">; def CR5 : CR<5, "CR5">; -def CR6 : CR<6, "CR6">; def CR7 : CR<7, "CR7">; - // Floating-point status and control register def FPSCR : SPR<0, "FPSCR">; // fiXed-point Exception Register? :-) From lattner at cs.uiuc.edu Fri Sep 30 01:44:57 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 01:44:57 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200509300644.BAA19697@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.31 -> 1.32 --- Log message: Compute a preferred spill register class for each callee-save register --- Diffs of the changes: (+24 -1) RegisterInfoEmitter.cpp | 25 ++++++++++++++++++++++++- 1 files changed, 24 insertions(+), 1 deletion(-) Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.31 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.32 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.31 Thu Sep 29 20:33:48 2005 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Fri Sep 30 01:44:45 2005 @@ -59,6 +59,7 @@ << " " << ClassName << "(int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n" << " const unsigned* getCalleeSaveRegs() const;\n" + << "const TargetRegisterClass* const *getCalleeSaveRegClasses() const;\n" << "};\n\n"; const std::vector &RegisterClasses = @@ -244,7 +245,7 @@ << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n " << " CallFrameSetupOpcode, CallFrameDestroyOpcode) {}\n\n"; - // Emit the getCalleeSaveRegs method... + // Emit the getCalleeSaveRegs method. OS << "const unsigned* " << ClassName << "::getCalleeSaveRegs() const {\n" << " static const unsigned CalleeSaveRegs[] = {\n "; @@ -252,5 +253,27 @@ for (unsigned i = 0, e = CSR.size(); i != e; ++i) OS << getQualifiedName(CSR[i]) << ", "; OS << " 0\n };\n return CalleeSaveRegs;\n}\n\n"; + + // Emit information about the callee saved register classes. + OS << "const TargetRegisterClass* const*\n" << ClassName + << "::getCalleeSaveRegClasses() const {\n" + << " static const TargetRegisterClass * const " + << "CalleeSaveRegClasses[] = {\n "; + + for (unsigned i = 0, e = CSR.size(); i != e; ++i) { + Record *R = CSR[i]; + std::multimap::iterator I, E; + tie(I, E) = RegClassesBelongedTo.equal_range(R); + if (I == E) + throw "Callee saved register '" + R->getName() + + "' must belong to a register class for spilling.\n"; + const CodeGenRegisterClass *RC = (I++)->second; + for (; I != E; ++I) + if (RC->SpillSize < I->second->SpillSize) + RC = I->second; + OS << "&" << getQualifiedName(RC->TheDef) << "RegClass, "; + } + OS << " 0\n };\n return CalleeSaveRegClasses;\n}\n\n"; + OS << "} // End llvm namespace \n"; } From lattner at cs.uiuc.edu Fri Sep 30 01:55:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 01:55:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9RegisterInfo.h Message-ID: <200509300655.BAA20227@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9RegisterInfo.h updated: 1.8 -> 1.9 --- Log message: stub out a virtual method --- Diffs of the changes: (+4 -0) SparcV9RegisterInfo.h | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/SparcV9/SparcV9RegisterInfo.h diff -u llvm/lib/Target/SparcV9/SparcV9RegisterInfo.h:1.8 llvm/lib/Target/SparcV9/SparcV9RegisterInfo.h:1.9 --- llvm/lib/Target/SparcV9/SparcV9RegisterInfo.h:1.8 Thu Sep 29 20:29:42 2005 +++ llvm/lib/Target/SparcV9/SparcV9RegisterInfo.h Fri Sep 30 01:55:18 2005 @@ -23,6 +23,10 @@ struct SparcV9RegisterInfo : public MRegisterInfo { SparcV9RegisterInfo (); const unsigned *getCalleeSaveRegs() const; + const TargetRegisterClass* const *getCalleeSaveRegClasses() const { + return 0; + } + // The rest of these are stubs... for now. void storeRegToStackSlot(MachineBasicBlock &MBB, From lattner at cs.uiuc.edu Fri Sep 30 02:06:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 02:06:49 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200509300706.CAA20772@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.59 -> 1.60 --- Log message: expose a new virtual method --- Diffs of the changes: (+7 -0) MRegisterInfo.h | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.59 llvm/include/llvm/Target/MRegisterInfo.h:1.60 --- llvm/include/llvm/Target/MRegisterInfo.h:1.59 Thu Sep 29 20:28:14 2005 +++ llvm/include/llvm/Target/MRegisterInfo.h Fri Sep 30 02:06:37 2005 @@ -25,6 +25,7 @@ class Type; class MachineFunction; class MachineInstr; +class TargetRegisterClass; /// MRegisterDesc - This record contains all of the information known about a /// particular register. The AliasSet field (if not null) contains a pointer to @@ -214,8 +215,14 @@ return false; } + /// getCalleeSaveRegs - Return a null-terminated list of all of the + /// callee-save registers on this target. virtual const unsigned* getCalleeSaveRegs() const = 0; + /// getCalleeSaveRegClasses - Return a null-terminated list of the preferred + /// register classes to spill each callee-saved register with. The order and + /// length of this list match the getCalleeSaveRegs() list. + virtual const TargetRegisterClass* const *getCalleeSaveRegClasses() const = 0; //===--------------------------------------------------------------------===// // Register Class Information From lattner at cs.uiuc.edu Fri Sep 30 11:59:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 11:59:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PrologEpilogInserter.cpp Message-ID: <200509301659.LAA24587@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: PrologEpilogInserter.cpp updated: 1.47 -> 1.48 --- Log message: Now that we have getCalleeSaveRegClasses() info, use it to pass the register class into the spill/reload methods. Targets can now rely on that argument. --- Diffs of the changes: (+11 -8) PrologEpilogInserter.cpp | 19 +++++++++++-------- 1 files changed, 11 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.47 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.48 --- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.47 Thu Sep 29 20:29:00 2005 +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp Fri Sep 30 11:59:07 2005 @@ -70,7 +70,7 @@ } private: - std::vector RegsToSave; + std::vector > RegsToSave; std::vector StackSlots; void calculateCallerSavedRegisters(MachineFunction &Fn); @@ -136,15 +136,18 @@ // function, thus needing to be saved and restored in the prolog/epilog. // const bool *PhysRegsUsed = Fn.getUsedPhysregs(); + const TargetRegisterClass* const *CSRegClasses = + RegInfo->getCalleeSaveRegClasses(); for (unsigned i = 0; CSRegs[i]; ++i) { unsigned Reg = CSRegs[i]; if (PhysRegsUsed[Reg]) { - RegsToSave.push_back(Reg); // If the reg is modified, save it! + // If the reg is modified, save it! + RegsToSave.push_back(std::make_pair(Reg, CSRegClasses[i])); } else { for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); *AliasSet; ++AliasSet) { // Check alias registers too. if (PhysRegsUsed[*AliasSet]) { - RegsToSave.push_back(Reg); + RegsToSave.push_back(std::make_pair(Reg, CSRegClasses[i])); break; } } @@ -161,7 +164,7 @@ // Now that we know which registers need to be saved and restored, allocate // stack slots for them. for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { - unsigned Reg = RegsToSave[i]; + unsigned Reg = RegsToSave[i].first; // Check to see if this physreg must be spilled to a particular stack slot // on this target. @@ -200,8 +203,8 @@ MachineBasicBlock::iterator I = MBB->begin(); for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { // Insert the spill to the stack frame. - RegInfo->storeRegToStackSlot(*MBB, I, RegsToSave[i], StackSlots[i], - 0 /*FIXME*/); + RegInfo->storeRegToStackSlot(*MBB, I, RegsToSave[i].first, StackSlots[i], + RegsToSave[i].second); } // Add code to restore the callee-save registers in each exiting block. @@ -226,8 +229,8 @@ // Restore all registers immediately before the return and any terminators // that preceed it. for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { - RegInfo->loadRegFromStackSlot(*MBB, I, RegsToSave[i], StackSlots[i], - 0 /*FIXME*/); + RegInfo->loadRegFromStackSlot(*MBB, I, RegsToSave[i].first, + StackSlots[i], RegsToSave[i].second); assert(I != MBB->begin() && "loadRegFromStackSlot didn't insert any code!"); // Insert in reverse order. loadRegFromStackSlot can insert multiple From lattner at cs.uiuc.edu Fri Sep 30 12:12:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 12:12:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <200509301712.MAA24925@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.110 -> 1.111 --- Log message: simplify this code using the new regclass info passed in --- Diffs of the changes: (+45 -29) X86RegisterInfo.cpp | 74 +++++++++++++++++++++++++++++++--------------------- 1 files changed, 45 insertions(+), 29 deletions(-) Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.110 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.111 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.110 Thu Sep 29 20:29:42 2005 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Fri Sep 30 12:12:38 2005 @@ -44,28 +44,25 @@ X86RegisterInfo::X86RegisterInfo() : X86GenRegisterInfo(X86::ADJCALLSTACKDOWN, X86::ADJCALLSTACKUP) {} -static unsigned getIdx(unsigned SpillSize) { - switch (SpillSize) { - default: assert(0 && "Invalid data size!"); - case 8: return 0; - case 16: return 1; - case 32: return 2; - case 64: return 3; // FP in 64-bit spill mode. - case 80: return 4; // FP in 80-bit spill mode. - case 128: return 5; // XMM reg in 128 bit mode. - } -} - void X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, int FrameIdx, const TargetRegisterClass *RC) const { - static const unsigned Opcode[] = - { X86::MOV8mr, X86::MOV16mr, X86::MOV32mr, X86::FST64m, X86::FSTP80m, - X86::MOVAPDmr }; - unsigned Idx = getIdx(getSpillSize(SrcReg)); - unsigned Opc = Opcode[Idx]; - if (X86ScalarSSE && Opc == X86::FST64m) Opc = X86::MOVSDmr; + unsigned Opc; + if (RC == &X86::R32RegClass) { + Opc = X86::MOV32mr; + } else if (RC == &X86::R8RegClass) { + Opc = X86::MOV8mr; + } else if (RC == &X86::R16RegClass) { + Opc = X86::MOV16mr; + } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { + Opc = X86::FST64m; + } else if (RC == &X86::RXMMRegClass) { + Opc = X86::MOVSDmr; + } else { + assert(0 && "Unknown regclass"); + abort(); + } addFrameReference(BuildMI(MBB, MI, Opc, 5), FrameIdx).addReg(SrcReg); } @@ -73,12 +70,21 @@ MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC) const{ - static const unsigned Opcode[] = - { X86::MOV8rm, X86::MOV16rm, X86::MOV32rm, X86::FLD64m, X86::FLD80m, - X86::MOVAPDrm }; - unsigned Idx = getIdx(getSpillSize(DestReg)); - unsigned Opc = Opcode[Idx]; - if (X86ScalarSSE && Opc == X86::FLD64m) Opc = X86::MOVSDrm; + unsigned Opc; + if (RC == &X86::R32RegClass) { + Opc = X86::MOV32rm; + } else if (RC == &X86::R8RegClass) { + Opc = X86::MOV8rm; + } else if (RC == &X86::R16RegClass) { + Opc = X86::MOV16rm; + } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { + Opc = X86::FLD64m; + } else if (RC == &X86::RXMMRegClass) { + Opc = X86::MOVSDrm; + } else { + assert(0 && "Unknown regclass"); + abort(); + } addFrameReference(BuildMI(MBB, MI, Opc, 4, DestReg), FrameIdx); } @@ -86,11 +92,21 @@ MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const { - static const unsigned Opcode[] = - { X86::MOV8rr, X86::MOV16rr, X86::MOV32rr, X86::FpMOV, X86::FpMOV, - X86::MOVAPDrr }; - unsigned Opc = Opcode[getIdx(RC->getSize()*8)]; - if (X86ScalarSSE && Opc == X86::FpMOV) Opc = X86::MOVAPDrr; + unsigned Opc; + if (RC == &X86::R32RegClass) { + Opc = X86::MOV32rr; + } else if (RC == &X86::R8RegClass) { + Opc = X86::MOV8rr; + } else if (RC == &X86::R16RegClass) { + Opc = X86::MOV16rr; + } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { + Opc = X86::FpMOV; + } else if (RC == &X86::RXMMRegClass) { + Opc = X86::MOVAPDrr; + } else { + assert(0 && "Unknown regclass"); + abort(); + } BuildMI(MBB, MI, Opc, 1, DestReg).addReg(SrcReg); } From lattner at cs.uiuc.edu Fri Sep 30 12:17:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 12:17:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Message-ID: <200509301717.MAA25014@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32RegisterInfo.cpp updated: 1.25 -> 1.26 --- Log message: constant fold these calls --- Diffs of the changes: (+2 -2) PPC32RegisterInfo.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.25 llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.26 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.25 Thu Sep 29 20:31:52 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Fri Sep 30 12:16:59 2005 @@ -307,7 +307,7 @@ // Add the size of R1 to NumBytes size for the store of R1 to the bottom // of the stack and round the size to a multiple of the alignment. unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); - unsigned GPRSize = getSpillSize(PPC::R1)/8; + unsigned GPRSize = 4; unsigned Size = hasFP(MF) ? GPRSize + GPRSize : GPRSize; NumBytes = (NumBytes+Size+Align-1)/Align*Align; @@ -347,7 +347,7 @@ // Get the number of bytes allocated from the FrameInfo... unsigned NumBytes = MFI->getStackSize(); - unsigned GPRSize = getSpillSize(PPC::R31)/8; + unsigned GPRSize = 4; if (NumBytes != 0) { if (hasFP(MF)) { From lattner at cs.uiuc.edu Fri Sep 30 12:19:34 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 12:19:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PrologEpilogInserter.cpp Message-ID: <200509301719.MAA25154@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: PrologEpilogInserter.cpp updated: 1.48 -> 1.49 --- Log message: now that we have a reg class to spill with, get this info from the regclass --- Diffs of the changes: (+3 -4) PrologEpilogInserter.cpp | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.48 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.49 --- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.48 Fri Sep 30 11:59:07 2005 +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp Fri Sep 30 12:19:22 2005 @@ -165,6 +165,7 @@ // stack slots for them. for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { unsigned Reg = RegsToSave[i].first; + const TargetRegisterClass *RC = RegsToSave[i].second; // Check to see if this physreg must be spilled to a particular stack slot // on this target. @@ -176,12 +177,10 @@ int FrameIdx; if (FixedSlot == FixedSpillSlots+NumFixedSpillSlots) { // Nope, just spill it anywhere convenient. - FrameIdx = FFI->CreateStackObject(RegInfo->getSpillSize(Reg)/8, - RegInfo->getSpillAlignment(Reg)/8); + FrameIdx = FFI->CreateStackObject(RC->getSize(), RC->getAlignment()); } else { // Spill it to the stack where we must. - FrameIdx = FFI->CreateFixedObject(RegInfo->getSpillSize(Reg)/8, - FixedSlot->second); + FrameIdx = FFI->CreateFixedObject(RC->getSize(), FixedSlot->second); } StackSlots.push_back(FrameIdx); } From lattner at cs.uiuc.edu Fri Sep 30 12:35:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 12:35:00 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200509301735.MAA25386@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.32 -> 1.33 --- Log message: trim down the target info structs now that we have a preferred spill register class for each callee save register --- Diffs of the changes: (+2 -17) RegisterInfoEmitter.cpp | 19 ++----------------- 1 files changed, 2 insertions(+), 17 deletions(-) Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.32 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.33 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.32 Fri Sep 30 01:44:45 2005 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Fri Sep 30 12:34:49 2005 @@ -214,24 +214,9 @@ OS << Reg.getName(); OS << "\",\t"; if (RegisterAliases.count(Reg.TheDef)) - OS << Reg.getName() << "_AliasSet,\t"; + OS << Reg.getName() << "_AliasSet },\n"; else - OS << "Empty_AliasSet,\t"; - - // Figure out what the size and alignment of the spill slots are for this - // reg. This may be explicitly declared in the register, or it may be - // inferred from the register classes it is part of. - std::multimap::iterator I, E; - tie(I, E) = RegClassesBelongedTo.equal_range(Reg.TheDef); - unsigned SpillSize = Reg.DeclaredSpillSize; - unsigned SpillAlign = Reg.DeclaredSpillAlignment; - for (; I != E; ++I) { // For each reg class this belongs to. - const CodeGenRegisterClass *RC = I->second; - SpillSize = std::max(SpillSize, RC->SpillSize); - SpillAlign = std::max(SpillAlign, RC->SpillAlignment); - } - - OS << SpillSize << ", " << SpillAlign << " },\n"; + OS << "Empty_AliasSet },\n"; } OS << " };\n"; // End of register descriptors... OS << "}\n\n"; // End of anonymous namespace... From lattner at cs.uiuc.edu Fri Sep 30 12:35:34 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 12:35:34 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200509301735.MAA25446@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.60 -> 1.61 --- Log message: trim down the target info structs now that we have a preferred spill register class for each callee save register --- Diffs of the changes: (+0 -14) MRegisterInfo.h | 14 -------------- 1 files changed, 14 deletions(-) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.60 llvm/include/llvm/Target/MRegisterInfo.h:1.61 --- llvm/include/llvm/Target/MRegisterInfo.h:1.60 Fri Sep 30 02:06:37 2005 +++ llvm/include/llvm/Target/MRegisterInfo.h Fri Sep 30 12:35:22 2005 @@ -36,8 +36,6 @@ struct MRegisterDesc { const char *Name; // Assembly language name for the register const unsigned *AliasSet; // Register Alias Set, described above - unsigned char SpillSize; // Size of this register in bytes - unsigned char SpillAlignment; // Alignment of stack slot for this reg }; class TargetRegisterClass { @@ -189,18 +187,6 @@ return get(RegNo).Name; } - /// getSpillSize - Return the size in bits required of a stack slot used to - /// spill register into. - unsigned getSpillSize(unsigned RegNo) const { - return get(RegNo).SpillSize; - } - - /// getSpillAlignment - Return the alignment required by a stack slot used to - /// spill register into. - unsigned getSpillAlignment(unsigned RegNo) const { - return get(RegNo).SpillAlignment; - } - /// getNumRegs - Return the number of registers this target has /// (useful for sizing arrays holding per register information) unsigned getNumRegs() const { From lattner at cs.uiuc.edu Fri Sep 30 12:38:47 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 12:38:47 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp Message-ID: <200509301738.MAA25496@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9RegisterInfo.cpp updated: 1.6 -> 1.7 --- Log message: trim down the target info structs now that we have a preferred spill register class for each callee save register Why is V9 maintaining these tables manually? ugh! --- Diffs of the changes: (+104 -104) SparcV9RegisterInfo.cpp | 208 ++++++++++++++++++++++++------------------------ 1 files changed, 104 insertions(+), 104 deletions(-) Index: llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp diff -u llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp:1.6 llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp:1.7 --- llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp:1.6 Thu Sep 29 20:29:42 2005 +++ llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp Fri Sep 30 12:38:36 2005 @@ -129,110 +129,110 @@ const unsigned ccr_AliasSet[] = { SparcV9::xcc, SparcV9::icc, 0 }; const MRegisterDesc RegisterDescriptors[] = { // Descriptors - { "o0", Empty_AliasSet, 0, 0 }, - { "o1", Empty_AliasSet, 0, 0 }, - { "o2", Empty_AliasSet, 0, 0 }, - { "o3", Empty_AliasSet, 0, 0 }, - { "o4", Empty_AliasSet, 0, 0 }, - { "o5", Empty_AliasSet, 0, 0 }, - { "o7", Empty_AliasSet, 0, 0 }, - { "l0", Empty_AliasSet, 0, 0 }, - { "l1", Empty_AliasSet, 0, 0 }, - { "l2", Empty_AliasSet, 0, 0 }, - { "l3", Empty_AliasSet, 0, 0 }, - { "l4", Empty_AliasSet, 0, 0 }, - { "l5", Empty_AliasSet, 0, 0 }, - { "l6", Empty_AliasSet, 0, 0 }, - { "l7", Empty_AliasSet, 0, 0 }, - { "i0", Empty_AliasSet, 0, 0 }, - { "i1", Empty_AliasSet, 0, 0 }, - { "i2", Empty_AliasSet, 0, 0 }, - { "i3", Empty_AliasSet, 0, 0 }, - { "i4", Empty_AliasSet, 0, 0 }, - { "i5", Empty_AliasSet, 0, 0 }, - { "i6", Empty_AliasSet, 0, 0 }, - { "i7", Empty_AliasSet, 0, 0 }, - { "g0", Empty_AliasSet, 0, 0 }, - { "g1", Empty_AliasSet, 0, 0 }, - { "g2", Empty_AliasSet, 0, 0 }, - { "g3", Empty_AliasSet, 0, 0 }, - { "g4", Empty_AliasSet, 0, 0 }, - { "g5", Empty_AliasSet, 0, 0 }, - { "g6", Empty_AliasSet, 0, 0 }, - { "g7", Empty_AliasSet, 0, 0 }, - { "o6", Empty_AliasSet, 0, 0 }, - { "f0", Empty_AliasSet, 0, 0 }, - { "f1", Empty_AliasSet, 0, 0 }, - { "f2", Empty_AliasSet, 0, 0 }, - { "f3", Empty_AliasSet, 0, 0 }, - { "f4", Empty_AliasSet, 0, 0 }, - { "f5", Empty_AliasSet, 0, 0 }, - { "f6", Empty_AliasSet, 0, 0 }, - { "f7", Empty_AliasSet, 0, 0 }, - { "f8", Empty_AliasSet, 0, 0 }, - { "f9", Empty_AliasSet, 0, 0 }, - { "f10", Empty_AliasSet, 0, 0 }, - { "f11", Empty_AliasSet, 0, 0 }, - { "f12", Empty_AliasSet, 0, 0 }, - { "f13", Empty_AliasSet, 0, 0 }, - { "f14", Empty_AliasSet, 0, 0 }, - { "f15", Empty_AliasSet, 0, 0 }, - { "f16", Empty_AliasSet, 0, 0 }, - { "f17", Empty_AliasSet, 0, 0 }, - { "f18", Empty_AliasSet, 0, 0 }, - { "f19", Empty_AliasSet, 0, 0 }, - { "f20", Empty_AliasSet, 0, 0 }, - { "f21", Empty_AliasSet, 0, 0 }, - { "f22", Empty_AliasSet, 0, 0 }, - { "f23", Empty_AliasSet, 0, 0 }, - { "f24", Empty_AliasSet, 0, 0 }, - { "f25", Empty_AliasSet, 0, 0 }, - { "f26", Empty_AliasSet, 0, 0 }, - { "f27", Empty_AliasSet, 0, 0 }, - { "f28", Empty_AliasSet, 0, 0 }, - { "f29", Empty_AliasSet, 0, 0 }, - { "f30", Empty_AliasSet, 0, 0 }, - { "f31", Empty_AliasSet, 0, 0 }, - { "f32", Empty_AliasSet, 0, 0 }, - { "f33", Empty_AliasSet, 0, 0 }, - { "f34", Empty_AliasSet, 0, 0 }, - { "f35", Empty_AliasSet, 0, 0 }, - { "f36", Empty_AliasSet, 0, 0 }, - { "f37", Empty_AliasSet, 0, 0 }, - { "f38", Empty_AliasSet, 0, 0 }, - { "f39", Empty_AliasSet, 0, 0 }, - { "f40", Empty_AliasSet, 0, 0 }, - { "f41", Empty_AliasSet, 0, 0 }, - { "f42", Empty_AliasSet, 0, 0 }, - { "f43", Empty_AliasSet, 0, 0 }, - { "f44", Empty_AliasSet, 0, 0 }, - { "f45", Empty_AliasSet, 0, 0 }, - { "f46", Empty_AliasSet, 0, 0 }, - { "f47", Empty_AliasSet, 0, 0 }, - { "f48", Empty_AliasSet, 0, 0 }, - { "f49", Empty_AliasSet, 0, 0 }, - { "f50", Empty_AliasSet, 0, 0 }, - { "f51", Empty_AliasSet, 0, 0 }, - { "f52", Empty_AliasSet, 0, 0 }, - { "f53", Empty_AliasSet, 0, 0 }, - { "f54", Empty_AliasSet, 0, 0 }, - { "f55", Empty_AliasSet, 0, 0 }, - { "f56", Empty_AliasSet, 0, 0 }, - { "f57", Empty_AliasSet, 0, 0 }, - { "f58", Empty_AliasSet, 0, 0 }, - { "f59", Empty_AliasSet, 0, 0 }, - { "f60", Empty_AliasSet, 0, 0 }, - { "f61", Empty_AliasSet, 0, 0 }, - { "f62", Empty_AliasSet, 0, 0 }, - { "f63", Empty_AliasSet, 0, 0 }, - { "xcc", xcc_AliasSet, 0, 0 }, - { "icc", icc_AliasSet, 0, 0 }, - { "ccr", ccr_AliasSet, 0, 0 }, - { "fcc0", fcc0_AliasSet, 0, 0 }, - { "fcc1", fcc1_AliasSet, 0, 0 }, - { "fcc2", fcc2_AliasSet, 0, 0 }, - { "fcc3", fcc3_AliasSet, 0, 0 }, - { "fsr", fsr_AliasSet, 0, 0 }, + { "o0", Empty_AliasSet }, + { "o1", Empty_AliasSet }, + { "o2", Empty_AliasSet }, + { "o3", Empty_AliasSet }, + { "o4", Empty_AliasSet }, + { "o5", Empty_AliasSet }, + { "o7", Empty_AliasSet }, + { "l0", Empty_AliasSet }, + { "l1", Empty_AliasSet }, + { "l2", Empty_AliasSet }, + { "l3", Empty_AliasSet }, + { "l4", Empty_AliasSet }, + { "l5", Empty_AliasSet }, + { "l6", Empty_AliasSet }, + { "l7", Empty_AliasSet }, + { "i0", Empty_AliasSet }, + { "i1", Empty_AliasSet }, + { "i2", Empty_AliasSet }, + { "i3", Empty_AliasSet }, + { "i4", Empty_AliasSet }, + { "i5", Empty_AliasSet }, + { "i6", Empty_AliasSet }, + { "i7", Empty_AliasSet }, + { "g0", Empty_AliasSet }, + { "g1", Empty_AliasSet }, + { "g2", Empty_AliasSet }, + { "g3", Empty_AliasSet }, + { "g4", Empty_AliasSet }, + { "g5", Empty_AliasSet }, + { "g6", Empty_AliasSet }, + { "g7", Empty_AliasSet }, + { "o6", Empty_AliasSet }, + { "f0", Empty_AliasSet }, + { "f1", Empty_AliasSet }, + { "f2", Empty_AliasSet }, + { "f3", Empty_AliasSet }, + { "f4", Empty_AliasSet }, + { "f5", Empty_AliasSet }, + { "f6", Empty_AliasSet }, + { "f7", Empty_AliasSet }, + { "f8", Empty_AliasSet }, + { "f9", Empty_AliasSet }, + { "f10", Empty_AliasSet }, + { "f11", Empty_AliasSet }, + { "f12", Empty_AliasSet }, + { "f13", Empty_AliasSet }, + { "f14", Empty_AliasSet }, + { "f15", Empty_AliasSet }, + { "f16", Empty_AliasSet }, + { "f17", Empty_AliasSet }, + { "f18", Empty_AliasSet }, + { "f19", Empty_AliasSet }, + { "f20", Empty_AliasSet }, + { "f21", Empty_AliasSet }, + { "f22", Empty_AliasSet }, + { "f23", Empty_AliasSet }, + { "f24", Empty_AliasSet }, + { "f25", Empty_AliasSet }, + { "f26", Empty_AliasSet }, + { "f27", Empty_AliasSet }, + { "f28", Empty_AliasSet }, + { "f29", Empty_AliasSet }, + { "f30", Empty_AliasSet }, + { "f31", Empty_AliasSet }, + { "f32", Empty_AliasSet }, + { "f33", Empty_AliasSet }, + { "f34", Empty_AliasSet }, + { "f35", Empty_AliasSet }, + { "f36", Empty_AliasSet }, + { "f37", Empty_AliasSet }, + { "f38", Empty_AliasSet }, + { "f39", Empty_AliasSet }, + { "f40", Empty_AliasSet }, + { "f41", Empty_AliasSet }, + { "f42", Empty_AliasSet }, + { "f43", Empty_AliasSet }, + { "f44", Empty_AliasSet }, + { "f45", Empty_AliasSet }, + { "f46", Empty_AliasSet }, + { "f47", Empty_AliasSet }, + { "f48", Empty_AliasSet }, + { "f49", Empty_AliasSet }, + { "f50", Empty_AliasSet }, + { "f51", Empty_AliasSet }, + { "f52", Empty_AliasSet }, + { "f53", Empty_AliasSet }, + { "f54", Empty_AliasSet }, + { "f55", Empty_AliasSet }, + { "f56", Empty_AliasSet }, + { "f57", Empty_AliasSet }, + { "f58", Empty_AliasSet }, + { "f59", Empty_AliasSet }, + { "f60", Empty_AliasSet }, + { "f61", Empty_AliasSet }, + { "f62", Empty_AliasSet }, + { "f63", Empty_AliasSet }, + { "xcc", xcc_AliasSet }, + { "icc", icc_AliasSet }, + { "ccr", ccr_AliasSet }, + { "fcc0", fcc0_AliasSet }, + { "fcc1", fcc1_AliasSet }, + { "fcc2", fcc2_AliasSet }, + { "fcc3", fcc3_AliasSet }, + { "fsr", fsr_AliasSet }, }; } // end anonymous namespace From lattner at cs.uiuc.edu Fri Sep 30 12:41:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 12:41:16 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200509301741.MAA25537@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.33 -> 1.34 --- Log message: remove some more initializers --- Diffs of the changes: (+1 -1) RegisterInfoEmitter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.33 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.34 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.33 Fri Sep 30 12:34:49 2005 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Fri Sep 30 12:41:05 2005 @@ -199,7 +199,7 @@ } OS << "\n const MRegisterDesc RegisterDescriptors[] = { // Descriptors\n"; - OS << " { \"NOREG\",\t0,\t\t0,\t0 },\n"; + OS << " { \"NOREG\",\t0 },\n"; // Now that register alias sets have been emitted, emit the register From lattner at cs.uiuc.edu Fri Sep 30 12:47:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 12:47:07 -0500 Subject: [llvm-commits] CVS: llvm/docs/CodeGenerator.html Message-ID: <200509301747.MAA25676@zion.cs.uiuc.edu> Changes in directory llvm/docs: CodeGenerator.html updated: 1.17 -> 1.18 --- Log message: Update the discussion of TargetRegisterDesc --- Diffs of the changes: (+4 -4) CodeGenerator.html | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/docs/CodeGenerator.html diff -u llvm/docs/CodeGenerator.html:1.17 llvm/docs/CodeGenerator.html:1.18 --- llvm/docs/CodeGenerator.html:1.17 Mon Jul 18 22:37:48 2005 +++ llvm/docs/CodeGenerator.html Fri Sep 30 12:46:55 2005 @@ -358,9 +358,9 @@ large.

Each register in the processor description has an associated -MRegisterDesc entry, which provides a textual name for the register -(used for assembly output and debugging dumps), a set of aliases (used to -indicate that one register overlaps with another), and some flag bits. +TargetRegisterDesc entry, which provides a textual name for the register +(used for assembly output and debugging dumps) and a set of aliases (used to +indicate that one register overlaps with another).

In addition to the per-register description, the MRegisterInfo class @@ -1032,7 +1032,7 @@ Chris Lattner
The LLVM Compiler Infrastructure
- Last modified: $Date: 2005/07/19 03:37:48 $ + Last modified: $Date: 2005/09/30 17:46:55 $ From lattner at cs.uiuc.edu Fri Sep 30 12:48:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 12:48:00 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200509301748.MAA25734@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.61 -> 1.62 --- Log message: Rename MRegisterDesc -> TargetRegisterDesc for consistency --- Diffs of the changes: (+13 -11) MRegisterInfo.h | 24 +++++++++++++----------- 1 files changed, 13 insertions(+), 11 deletions(-) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.61 llvm/include/llvm/Target/MRegisterInfo.h:1.62 --- llvm/include/llvm/Target/MRegisterInfo.h:1.61 Fri Sep 30 12:35:22 2005 +++ llvm/include/llvm/Target/MRegisterInfo.h Fri Sep 30 12:47:48 2005 @@ -27,13 +27,13 @@ class MachineInstr; class TargetRegisterClass; -/// MRegisterDesc - This record contains all of the information known about a -/// particular register. The AliasSet field (if not null) contains a pointer to -/// a Zero terminated array of registers that this register aliases. This is +/// TargetRegisterDesc - This record contains all of the information known about +/// a particular register. The AliasSet field (if not null) contains a pointer +/// to a Zero terminated array of registers that this register aliases. This is /// needed for architectures like X86 which have AL alias AX alias EAX. /// Registers that this does not apply to simply should set this to null. /// -struct MRegisterDesc { +struct TargetRegisterDesc { const char *Name; // Assembly language name for the register const unsigned *AliasSet; // Register Alias Set, described above }; @@ -105,22 +105,22 @@ /// MRegisterInfo base class - We assume that the target defines a static array -/// of MRegisterDesc objects that represent all of the machine registers that -/// the target has. As such, we simply have to track a pointer to this array so -/// that we can turn register number into a register descriptor. +/// of TargetRegisterDesc objects that represent all of the machine registers +/// that the target has. As such, we simply have to track a pointer to this +/// array so that we can turn register number into a register descriptor. /// class MRegisterInfo { public: typedef const TargetRegisterClass * const * regclass_iterator; private: - const MRegisterDesc *Desc; // Pointer to the descriptor array + const TargetRegisterDesc *Desc; // Pointer to the descriptor array unsigned NumRegs; // Number of entries in the array regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses int CallFrameSetupOpcode, CallFrameDestroyOpcode; protected: - MRegisterInfo(const MRegisterDesc *D, unsigned NR, + MRegisterInfo(const TargetRegisterDesc *D, unsigned NR, regclass_iterator RegClassBegin, regclass_iterator RegClassEnd, int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1); virtual ~MRegisterInfo(); @@ -162,7 +162,7 @@ /// indicating if a register is allocatable or not. std::vector getAllocatableSet(MachineFunction &MF) const; - const MRegisterDesc &operator[](unsigned RegNo) const { + const TargetRegisterDesc &operator[](unsigned RegNo) const { assert(RegNo < NumRegs && "Attempting to access record for invalid register number!"); return Desc[RegNo]; @@ -171,7 +171,9 @@ /// Provide a get method, equivalent to [], but more useful if we have a /// pointer to this object. /// - const MRegisterDesc &get(unsigned RegNo) const { return operator[](RegNo); } + const TargetRegisterDesc &get(unsigned RegNo) const { + return operator[](RegNo); + } /// getAliasSet - Return the set of registers aliased by the specified /// register, or a null list of there are none. The list returned is zero From lattner at cs.uiuc.edu Fri Sep 30 12:48:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 12:48:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/MRegisterInfo.cpp Message-ID: <200509301748.MAA25767@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: MRegisterInfo.cpp updated: 1.10 -> 1.11 --- Log message: Rename MRegisterDesc -> TargetRegisterDesc for consistency --- Diffs of the changes: (+1 -1) MRegisterInfo.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/MRegisterInfo.cpp diff -u llvm/lib/Target/MRegisterInfo.cpp:1.10 llvm/lib/Target/MRegisterInfo.cpp:1.11 --- llvm/lib/Target/MRegisterInfo.cpp:1.10 Fri Apr 22 12:49:49 2005 +++ llvm/lib/Target/MRegisterInfo.cpp Fri Sep 30 12:48:18 2005 @@ -15,7 +15,7 @@ namespace llvm { -MRegisterInfo::MRegisterInfo(const MRegisterDesc *D, unsigned NR, +MRegisterInfo::MRegisterInfo(const TargetRegisterDesc *D, unsigned NR, regclass_iterator RCB, regclass_iterator RCE, int CFSO, int CFDO) : Desc(D), NumRegs(NR), RegClassBegin(RCB), RegClassEnd(RCE) { From lattner at cs.uiuc.edu Fri Sep 30 12:48:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 12:48:56 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200509301748.MAA25824@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.34 -> 1.35 --- Log message: Rename MRegisterDesc -> TargetRegisterDesc for consistency --- Diffs of the changes: (+1 -1) RegisterInfoEmitter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.34 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.35 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.34 Fri Sep 30 12:41:05 2005 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Fri Sep 30 12:48:44 2005 @@ -198,7 +198,7 @@ OS << "0 };\n"; } - OS << "\n const MRegisterDesc RegisterDescriptors[] = { // Descriptors\n"; + OS<<"\n const TargetRegisterDesc RegisterDescriptors[] = { // Descriptors\n"; OS << " { \"NOREG\",\t0 },\n"; From lattner at cs.uiuc.edu Fri Sep 30 12:49:39 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 12:49:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp Message-ID: <200509301749.MAA25883@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9RegisterInfo.cpp updated: 1.7 -> 1.8 --- Log message: Rename MRegisterDesc -> TargetRegisterDesc for consistency --- Diffs of the changes: (+1 -1) SparcV9RegisterInfo.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp diff -u llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp:1.7 llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp:1.8 --- llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp:1.7 Fri Sep 30 12:38:36 2005 +++ llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp Fri Sep 30 12:49:27 2005 @@ -128,7 +128,7 @@ const unsigned icc_AliasSet[] = { SparcV9::ccr, 0 }; const unsigned ccr_AliasSet[] = { SparcV9::xcc, SparcV9::icc, 0 }; -const MRegisterDesc RegisterDescriptors[] = { // Descriptors +const TargetRegisterDesc RegisterDescriptors[] = { // Descriptors { "o0", Empty_AliasSet }, { "o1", Empty_AliasSet }, { "o2", Empty_AliasSet }, From jlaskey at apple.com Fri Sep 30 14:12:05 2005 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 30 Sep 2005 14:12:05 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/GraphWriter.h Message-ID: <200509301912.OAA26928@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: GraphWriter.h updated: 1.23 -> 1.24 --- Log message: Add the node name (thus the address) to node label. --- Diffs of the changes: (+1 -1) GraphWriter.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Support/GraphWriter.h diff -u llvm/include/llvm/Support/GraphWriter.h:1.23 llvm/include/llvm/Support/GraphWriter.h:1.24 --- llvm/include/llvm/Support/GraphWriter.h:1.23 Thu Apr 21 15:44:59 2005 +++ llvm/include/llvm/Support/GraphWriter.h Fri Sep 30 14:11:53 2005 @@ -134,7 +134,7 @@ if (DOTTraits::renderGraphFromBottomUp()) O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G)); - O << "}\"];\n"; // Finish printing the "node" line + O << "|\\N}\"];\n"; // Finish printing the "node" line // Output all of the edges now EI = GTraits::child_begin(Node); From jlaskey at apple.com Fri Sep 30 14:15:38 2005 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 30 Sep 2005 14:15:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200509301915.OAA26952@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.25 -> 1.26 --- Log message: 1. Made things node-centric (from operand). 2. Added node groups to handle flagged nodes. 3. Started weaning simple scheduling off existing emitter. --- Diffs of the changes: (+609 -244) ScheduleDAG.cpp | 853 +++++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 609 insertions(+), 244 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.25 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.26 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.25 Wed Sep 28 20:59:49 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Sep 30 14:15:27 2005 @@ -192,25 +192,177 @@ //===----------------------------------------------------------------------===// -// This struct tracks information used to schedule the a node. -struct ScheduleInfo { - SDOperand Op; // Operand information +/// +/// Node group - This struct is used to manage flagged node groups. +/// +class NodeInfo; +class NodeGroup : public std::vector { +private: + int Pending; // Number of visits pending before + // adding to order + +public: + // Ctor. + NodeGroup() : Pending(0) {} + + // Accessors + inline NodeInfo *getLeader() { return empty() ? NULL : front(); } + inline int getPending() const { return Pending; } + inline void setPending(int P) { Pending = P; } + inline int addPending(int I) { return Pending += I; } + + static void Add(NodeInfo *D, NodeInfo *U); + static unsigned CountInternalUses(NodeInfo *D, NodeInfo *U); +}; +//===----------------------------------------------------------------------===// + + +//===----------------------------------------------------------------------===// +/// +/// NodeInfo - This struct tracks information used to schedule the a node. +/// +class NodeInfo { +private: + int Pending; // Number of visits pending before + // adding to order +public: + SDNode *Node; // DAG node unsigned Latency; // Cycles to complete instruction unsigned ResourceSet; // Bit vector of usable resources - unsigned Slot; // Operand's time slot + unsigned Slot; // Node's time slot + NodeGroup *Group; // Grouping information + unsigned VRBase; // Virtual register base // Ctor. - ScheduleInfo(SDOperand op) - : Op(op) + NodeInfo(SDNode *N = NULL) + : Pending(0) + , Node(N) , Latency(0) , ResourceSet(0) , Slot(0) + , Group(NULL) + , VRBase(0) {} + + // Accessors + inline bool isInGroup() const { + assert(!Group || !Group->empty() && "Group with no members"); + return Group != NULL; + } + inline bool isGroupLeader() const { + return isInGroup() && Group->getLeader() == this; + } + inline int getPending() const { + return Group ? Group->getPending() : Pending; + } + inline void setPending(int P) { + if (Group) Group->setPending(P); + else Pending = P; + } + inline int addPending(int I) { + if (Group) return Group->addPending(I); + else return Pending += I; + } +}; +typedef std::vector::iterator NIIterator; +//===----------------------------------------------------------------------===// + + +//===----------------------------------------------------------------------===// +/// +/// NodeGroupIterator - Iterates over all the nodes indicated by the node info. +/// If the node is in a group then iterate over the members of the group, +/// otherwise just the node info. +/// +class NodeGroupIterator { +private: + NodeInfo *NI; // Node info + NIIterator NGI; // Node group iterator + NIIterator NGE; // Node group iterator end + +public: + // Ctor. + NodeGroupIterator(NodeInfo *N) : NI(N) { + // If the node is in a group then set up the group iterator. Otherwise + // the group iterators will trip first time out. + if (N->isInGroup()) { + // get Group + NodeGroup *Group = NI->Group; + NGI = Group->begin(); + NGE = Group->end(); + // Prevent this node from being used (will be in members list + NI = NULL; + } + } + + /// next - Return the next node info, otherwise NULL. + /// + NodeInfo *next() { + // If members list + if (NGI != NGE) return *NGI++; + // Use node as the result (may be NULL) + NodeInfo *Result = NI; + // Only use once + NI = NULL; + // Return node or NULL + return Result; + } +}; +//===----------------------------------------------------------------------===// + + +//===----------------------------------------------------------------------===// +/// +/// NodeGroupOpIterator - Iterates over all the operands of a node. If the node +/// is a member of a group, this iterates over all the operands of all the +/// members of the group. +/// +class NodeGroupOpIterator { +private: + NodeInfo *NI; // Node containing operands + NodeGroupIterator GI; // Node group iterator + SDNode::op_iterator OI; // Operand iterator + SDNode::op_iterator OE; // Operand iterator end + + /// CheckNode - Test if node has more operands. If not get the next node + /// skipping over nodes that have no operands. + void CheckNode() { + // Only if operands are exhausted first + while (OI == OE) { + // Get next node info + NodeInfo *NI = GI.next(); + // Exit if nodes are exhausted + if (!NI) return; + // Get node itself + SDNode *Node = NI->Node; + // Set up the operand iterators + OI = Node->op_begin(); + OE = Node->op_end(); + } + } + +public: + // Ctor. + NodeGroupOpIterator(NodeInfo *N) : NI(N), GI(N) {} + + /// isEnd - Returns true when not more operands are available. + /// + inline bool isEnd() { CheckNode(); return OI == OE; } + + /// next - Returns the next available operand. + /// + inline SDOperand next() { + assert(OI != OE && "Not checking for end of NodeGroupOpIterator correctly"); + return *OI++; + } }; //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// +/// +/// SimpleSched - Simple two pass scheduler. +/// class SimpleSched { private: // TODO - get ResourceSet from TII @@ -228,12 +380,13 @@ const MRegisterInfo &MRI; // Target processor register information SSARegMap *RegMap; // Virtual/real register map MachineConstantPool *ConstPool; // Target constant pool - std::vector Operands; // All operands to be scheduled - std::vector Ordering; // Emit ordering of operands - std::map Visited; // Operands that have been visited + unsigned NodeCount; // Number of nodes in DAG + NodeInfo *Info; // Info for nodes being scheduled + std::map Map; // Map nodes to info + std::vector Ordering; // Emit ordering of nodes ResourceTally Tally; // Resource usage tally unsigned NSlots; // Total latency - std::mapVRMap; // Operand to VR map + std::map VRMap; // Node to VR map static const unsigned NotFound = ~0U; // Search marker public: @@ -255,37 +408,41 @@ } private: - static bool isFlagDefiner(SDOperand Op) { return isFlagDefiner(Op.Val); } - static bool isFlagUser(SDOperand Op) { return isFlagUser(Op.Val); } + /// getNI - Returns the node info for the specified node. + /// + inline NodeInfo *getNI(SDNode *Node) { return Map[Node]; } + + /// getVR - Returns the virtual register number of the node. + /// + inline unsigned getVR(SDOperand Op) { + NodeInfo *NI = getNI(Op.Val); + assert(NI->VRBase != 0 && "Node emitted out of order - late"); + return NI->VRBase + Op.ResNo; + } + static bool isFlagDefiner(SDNode *A); static bool isFlagUser(SDNode *A); - static bool isDefiner(SDNode *A, SDNode *B); - static bool isPassiveOperand(SDOperand Op); - void IncludeOperand(SDOperand Op); + static bool isDefiner(NodeInfo *A, NodeInfo *B); + static bool isPassiveNode(SDNode *Node); + void IncludeNode(NodeInfo *NI); void VisitAll(); void Schedule(); - void GatherOperandInfo(); - bool isStrongDependency(SDOperand A, SDOperand B) { - return isStrongDependency(A.Val, B.Val); - } - bool isWeakDependency(SDOperand A, SDOperand B) { - return isWeakDependency(A.Val, B.Val); - } - static bool isStrongDependency(SDNode *A, SDNode *B); - static bool isWeakDependency(SDNode *A, SDNode *B); + void GatherNodeInfo(); + bool isStrongDependency(NodeInfo *A, NodeInfo *B); + bool isWeakDependency(NodeInfo *A, NodeInfo *B); void ScheduleBackward(); void ScheduleForward(); void EmitAll(); - void EmitFlagUsers(SDOperand Op); - static unsigned CountResults(SDOperand Op); - static unsigned CountOperands(SDOperand Op); - unsigned CreateVirtualRegisters(SDOperand Op, MachineInstr *MI, + void EmitNode(NodeInfo *NI); + static unsigned CountResults(SDNode *Node); + static unsigned CountOperands(SDNode *Node); + unsigned CreateVirtualRegisters(MachineInstr *MI, unsigned NumResults, const TargetInstrDescriptor &II); - unsigned Emit(SDOperand A); + unsigned EmitDAG(SDOperand A); - void printSI(std::ostream &O, ScheduleInfo *SI) const ; - void print(std::ostream &O) const ; + void printSI(std::ostream &O, NodeInfo *NI) const; + void print(std::ostream &O) const; inline void dump(const char *tag) const { std::cerr << tag; dump(); } void dump() const; }; @@ -341,193 +498,284 @@ }; } // namespace +//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// -/// isFlagDefiner - Returns true if the operand defines a flag result. +/// Add - Adds a definer and user pair to a node group. +/// +void NodeGroup::Add(NodeInfo *D, NodeInfo *U) { + // Get current groups + NodeGroup *DGroup = D->Group; + NodeGroup *UGroup = U->Group; + // If both are members of groups + if (DGroup && UGroup) { + // There may have been another edge connecting + if (DGroup == UGroup) return; + // Add the pending users count + DGroup->addPending(UGroup->getPending()); + // For each member of the users group + NodeGroupIterator UNGI(U); + while (NodeInfo *UNI = UNGI.next() ) { + // Change the group + UNI->Group = DGroup; + // For each member of the definers group + NodeGroupIterator DNGI(D); + while (NodeInfo *DNI = DNGI.next() ) { + // Remove internal edges + DGroup->addPending(-CountInternalUses(DNI, UNI)); + } + } + // Merge the two lists + DGroup->insert(DGroup->end(), UGroup->begin(), UGroup->end()); + } else if (DGroup) { + // Make user member of definers group + U->Group = DGroup; + // Add users uses to definers group pending + DGroup->addPending(U->Node->use_size()); + // For each member of the definers group + NodeGroupIterator DNGI(D); + while (NodeInfo *DNI = DNGI.next() ) { + // Remove internal edges + DGroup->addPending(-CountInternalUses(DNI, U)); + } + DGroup->push_back(U); + } else if (UGroup) { + // Make definer member of users group + D->Group = UGroup; + // Add definers uses to users group pending + UGroup->addPending(D->Node->use_size()); + // For each member of the users group + NodeGroupIterator UNGI(U); + while (NodeInfo *UNI = UNGI.next() ) { + // Remove internal edges + UGroup->addPending(-CountInternalUses(D, UNI)); + } + UGroup->insert(UGroup->begin(), D); + } else { + D->Group = U->Group = DGroup = new NodeGroup(); + DGroup->addPending(D->Node->use_size() + U->Node->use_size() - + CountInternalUses(D, U)); + DGroup->push_back(D); + DGroup->push_back(U); + } +} + +/// CountInternalUses - Returns the number of edges between the two nodes. +/// +unsigned NodeGroup::CountInternalUses(NodeInfo *D, NodeInfo *U) { + unsigned N = 0; + for (SDNode:: use_iterator UI = D->Node->use_begin(), + E = D->Node->use_end(); UI != E; UI++) { + if (*UI == U->Node) N++; + } + return N; +} +//===----------------------------------------------------------------------===// + + +//===----------------------------------------------------------------------===// +/// isFlagDefiner - Returns true if the node defines a flag result. bool SimpleSched::isFlagDefiner(SDNode *A) { unsigned N = A->getNumValues(); return N && A->getValueType(N - 1) == MVT::Flag; } -/// isFlagUser - Returns true if the operand uses a flag result. +/// isFlagUser - Returns true if the node uses a flag result. /// bool SimpleSched::isFlagUser(SDNode *A) { unsigned N = A->getNumOperands(); return N && A->getOperand(N - 1).getValueType() == MVT::Flag; } -/// isDefiner - Return true if Node A is a definder for B. +/// isDefiner - Return true if node A is a definer for B. /// -bool SimpleSched::isDefiner(SDNode *A, SDNode *B) { - for (unsigned i = 0, N = B->getNumOperands(); i < N; i++) { - if (B->getOperand(i).Val == A) return true; +bool SimpleSched::isDefiner(NodeInfo *A, NodeInfo *B) { + // While there are A nodes + NodeGroupIterator NII(A); + while (NodeInfo *NI = NII.next()) { + // Extract node + SDNode *Node = NI->Node; + // While there operands in nodes of B + NodeGroupOpIterator NGOI(B); + while (!NGOI.isEnd()) { + SDOperand Op = NGOI.next(); + // If node from A defines a node in B + if (Node == Op.Val) return true; + } } return false; } -/// isPassiveOperand - Return true if the operand is a non-scheduled leaf -/// operand. -bool SimpleSched::isPassiveOperand(SDOperand Op) { - if (isa(Op)) return true; - if (isa(Op)) return true; - if (isa(Op)) return true; - if (isa(Op)) return true; - if (isa(Op)) return true; - if (isa(Op)) return true; - if (isa(Op)) return true; +/// isPassiveNode - Return true if the node is a non-scheduled leaf. +/// +bool SimpleSched::isPassiveNode(SDNode *Node) { + if (isa(Node)) return true; + if (isa(Node)) return true; + if (isa(Node)) return true; + if (isa(Node)) return true; + if (isa(Node)) return true; + if (isa(Node)) return true; + if (isa(Node)) return true; return false; } -/// IncludeOperand - Add operand to ScheduleInfo vector. +/// IncludeNode - Add node to NodeInfo vector. /// -void SimpleSched::IncludeOperand(SDOperand Op) { +void SimpleSched::IncludeNode(NodeInfo *NI) { + // Get node + SDNode *Node = NI->Node; // Ignore entry node - if (Op.getOpcode() == ISD::EntryToken) return; - // Check current count for operand - int Count = Visited[Op.Val]; - // If the operand is already in list +if (Node->getOpcode() == ISD::EntryToken) return; + // Check current count for node + int Count = NI->getPending(); + // If the node is already in list if (Count < 0) return; - // If this the first time then get count - if (!Count) Count = Op.Val->use_size(); // Decrement count to indicate a visit Count--; - // If count has gone to zero then add operand to list + // If count has gone to zero then add node to list if (!Count) { - // Add operand - Operands.push_back(ScheduleInfo(Op)); - // indicate operand has been added + // Add node + if (NI->isInGroup()) { + Ordering.push_back(NI->Group->getLeader()); + } else { + Ordering.push_back(NI); + } + // indicate node has been added Count--; } // Mark as visited with new count - Visited[Op.Val] = Count; + NI->setPending(Count); } -/// VisitAll - Visit each operand breadth-wise to produce an initial ordering. -/// Note that the ordering in the Operands vector is reversed. +/// VisitAll - Visit each node breadth-wise to produce an initial ordering. +/// Note that the ordering in the Nodes vector is reversed. void SimpleSched::VisitAll() { // Add first element to list - Operands.push_back(DAG.getRoot()); - for (unsigned i = 0; i < Operands.size(); i++) { // note: size() varies - // Get next operand. Need copy because Operands vector is growing and - // addresses can be ScheduleInfo changing. - SDOperand Op = Operands[i].Op; - // Get the number of real operands - unsigned NodeOperands = CountOperands(Op); - // Get the total number of operands - unsigned NumOperands = Op.getNumOperands(); - - // Visit all operands skipping the Other operand if present - for (unsigned i = NumOperands; 0 < i--;) { - SDOperand OpI = Op.getOperand(i); - // Ignore passive operands - if (isPassiveOperand(OpI)) continue; - // Check out operand - IncludeOperand(OpI); + Ordering.push_back(getNI(DAG.getRoot().Val)); + + // Iterate through all nodes that have been added + for (unsigned i = 0; i < Ordering.size(); i++) { // note: size() varies + // Visit all operands + NodeGroupOpIterator NGI(Ordering[i]); + while (!NGI.isEnd()) { + // Get next operand + SDOperand Op = NGI.next(); + // Get node + SDNode *Node = Op.Val; + // Ignore passive nodes + if (isPassiveNode(Node)) continue; + // Check out node + IncludeNode(getNI(Node)); } } - // Add entry node last (IncludeOperand filters entry nodes) + // Add entry node last (IncludeNode filters entry nodes) if (DAG.getEntryNode().Val != DAG.getRoot().Val) - Operands.push_back(DAG.getEntryNode()); + Ordering.push_back(getNI(DAG.getEntryNode().Val)); + + // FIXME - Reverse the order + for (unsigned i = 0, N = Ordering.size(), Half = N >> 1; i < Half; i++) { + unsigned j = N - i - 1; + NodeInfo *tmp = Ordering[i]; + Ordering[i] = Ordering[j]; + Ordering[j] = tmp; + } } -/// GatherOperandInfo - Get latency and resource information about each operand. -/// -void SimpleSched::GatherOperandInfo() { - // Add addresses of operand info to ordering vector - // Get number of operands - unsigned N = Operands.size(); - // FIXME: This is an ugly (but temporary!) hack to test the scheduler before - // we have real target info. +/// GatherNodeInfo - Get latency and resource information about each node. +/// +void SimpleSched::GatherNodeInfo() { + // Allocate node information + Info = new NodeInfo[NodeCount]; + // Get base of all nodes table + SelectionDAG::allnodes_iterator AllNodes = DAG.allnodes_begin(); - // For each operand being scheduled - for (unsigned i = 0; i < N; i++) { - ScheduleInfo* SI = &Operands[N - i - 1]; - SDOperand Op = SI->Op; - MVT::ValueType VT = Op.Val->getValueType(0); - if (Op.isTargetOpcode()) { - MachineOpCode TOpc = Op.getTargetOpcode(); - // FIXME SI->Latency = std::max(1, TII.maxLatency(TOpc)); - // FIXME SI->ResourceSet = TII.resources(TOpc); + // For each node being scheduled + for (unsigned i = 0, N = NodeCount; i < N; i++) { + // Get next node from DAG all nodes table + SDNode *Node = AllNodes[i]; + // Fast reference to node schedule info + NodeInfo* NI = &Info[i]; + // Set up map + Map[Node] = NI; + // Set node + NI->Node = Node; + // Set pending visit count + NI->setPending(Node->use_size()); + + MVT::ValueType VT = Node->getValueType(0); + if (Node->isTargetOpcode()) { + MachineOpCode TOpc = Node->getTargetOpcode(); + // FIXME: This is an ugly (but temporary!) hack to test the scheduler + // before we have real target info. + // FIXME NI->Latency = std::max(1, TII.maxLatency(TOpc)); + // FIXME NI->ResourceSet = TII.resources(TOpc); if (TII.isCall(TOpc)) { - SI->ResourceSet = RSInteger; - SI->Latency = 40; + NI->ResourceSet = RSInteger; + NI->Latency = 40; } else if (TII.isLoad(TOpc)) { - SI->ResourceSet = RSLoadStore; - SI->Latency = 5; + NI->ResourceSet = RSLoadStore; + NI->Latency = 5; } else if (TII.isStore(TOpc)) { - SI->ResourceSet = RSLoadStore; - SI->Latency = 2; + NI->ResourceSet = RSLoadStore; + NI->Latency = 2; } else if (MVT::isInteger(VT)) { - SI->ResourceSet = RSInteger; - SI->Latency = 2; + NI->ResourceSet = RSInteger; + NI->Latency = 2; } else if (MVT::isFloatingPoint(VT)) { - SI->ResourceSet = RSFloat; - SI->Latency = 3; + NI->ResourceSet = RSFloat; + NI->Latency = 3; } else { - SI->ResourceSet = RSOther; - SI->Latency = 0; + NI->ResourceSet = RSOther; + NI->Latency = 0; } } else { if (MVT::isInteger(VT)) { - SI->ResourceSet = RSInteger; - SI->Latency = 2; + NI->ResourceSet = RSInteger; + NI->Latency = 2; } else if (MVT::isFloatingPoint(VT)) { - SI->ResourceSet = RSFloat; - SI->Latency = 3; + NI->ResourceSet = RSFloat; + NI->Latency = 3; } else { - SI->ResourceSet = RSOther; - SI->Latency = 0; + NI->ResourceSet = RSOther; + NI->Latency = 0; } } // Add one slot for the instruction itself - SI->Latency++; + NI->Latency++; // Sum up all the latencies for max tally size - NSlots += SI->Latency; - - // Place in initial sorted order - // FIXME - PUNT - ignore flag users - if (!isFlagUser(Op)) Ordering.push_back(SI); + NSlots += NI->Latency; + } + + // Put flagged nodes into groups + for (unsigned i = 0, N = NodeCount; i < N; i++) { + NodeInfo* NI = &Info[i]; + SDNode *Node = NI->Node; + if (isFlagDefiner(Node)) { + FlagUserIterator FI(Node); + while (SDNode *User = FI.next()) NodeGroup::Add(NI, getNI(User)); + } } } -/// isStrongDependency - Return true if operand A has results used by operand B. +/// isStrongDependency - Return true if node A has results used by node B. /// I.E., B must wait for latency of A. -bool SimpleSched::isStrongDependency(SDNode *A, SDNode *B) { +bool SimpleSched::isStrongDependency(NodeInfo *A, NodeInfo *B) { // If A defines for B then it's a strong dependency - if (isDefiner(A, B)) return true; - // If A defines a flag then it's users are part of the dependency - if (isFlagDefiner(A)) { - // Check each flag user - FlagUserIterator FI(A); - while (SDNode *User = FI.next()) { - // If flag user has strong dependency so does B - if (isStrongDependency(User, B)) return true; - } - } - // If B defines a flag then it's users are part of the dependency - if (isFlagDefiner(B)) { - // Check each flag user - FlagUserIterator FI(B); - while (SDNode *User = FI.next()) { - // If flag user has strong dependency so does B - if (isStrongDependency(A, User)) return true; - } - } - return false; + return isDefiner(A, B); } -/// isWeakDependency Return true if operand A produces a result that will +/// isWeakDependency Return true if node A produces a result that will /// conflict with operands of B. -bool SimpleSched::isWeakDependency(SDNode *A, SDNode *B) { +bool SimpleSched::isWeakDependency(NodeInfo *A, NodeInfo *B) { // TODO check for conflicting real registers and aliases -#if 0 // Since we are in SSA form and not checking register aliasing - return A->getOpcode() == ISD::EntryToken || isStrongDependency(B, A); +#if 0 // FIXME - Since we are in SSA form and not checking register aliasing + return A->Node->getOpcode() == ISD::EntryToken || isStrongDependency(B, A); #else - return A->getOpcode() == ISD::EntryToken; + return A->Node->getOpcode() == ISD::EntryToken; #endif } @@ -538,26 +786,26 @@ void SimpleSched::ScheduleBackward() { // Size and clear the resource tally Tally.Initialize(NSlots); - // Get number of operands to schedule + // Get number of nodes to schedule unsigned N = Ordering.size(); - // For each operand being scheduled + // For each node being scheduled for (unsigned i = N; 0 < i--;) { - ScheduleInfo *SI = Ordering[i]; + NodeInfo *NI = Ordering[i]; // Track insertion unsigned Slot = NotFound; - // Compare against those previously scheduled operands + // Compare against those previously scheduled nodes unsigned j = i + 1; for (; j < N; j++) { // Get following instruction - ScheduleInfo *Other = Ordering[j]; + NodeInfo *Other = Ordering[j]; - // Check dependency against previously inserted operands - if (isStrongDependency(SI->Op, Other->Op)) { + // Check dependency against previously inserted nodes + if (isStrongDependency(NI, Other)) { Slot = Other->Slot + Other->Latency; break; - } else if (isWeakDependency(SI->Op, Other->Op)) { + } else if (isWeakDependency(NI, Other)) { Slot = Other->Slot; break; } @@ -567,24 +815,24 @@ if (Slot == NotFound) Slot = 0; // Find a slot where the needed resources are available - if (SI->ResourceSet) - Slot = Tally.FindAndReserve(Slot, SI->Latency, SI->ResourceSet); + if (NI->ResourceSet) + Slot = Tally.FindAndReserve(Slot, NI->Latency, NI->ResourceSet); - // Set operand slot - SI->Slot = Slot; + // Set node slot + NI->Slot = Slot; // Insert sort based on slot j = i + 1; for (; j < N; j++) { // Get following instruction - ScheduleInfo *Other = Ordering[j]; + NodeInfo *Other = Ordering[j]; // Should we look further if (Slot >= Other->Slot) break; // Shuffle other into ordering Ordering[j - 1] = Other; } - // Insert operand in proper slot - if (j != i + 1) Ordering[j - 1] = SI; + // Insert node in proper slot + if (j != i + 1) Ordering[j - 1] = NI; } } @@ -593,26 +841,26 @@ void SimpleSched::ScheduleForward() { // Size and clear the resource tally Tally.Initialize(NSlots); - // Get number of operands to schedule + // Get number of nodes to schedule unsigned N = Ordering.size(); - // For each operand being scheduled + // For each node being scheduled for (unsigned i = 0; i < N; i++) { - ScheduleInfo *SI = Ordering[i]; + NodeInfo *NI = Ordering[i]; // Track insertion unsigned Slot = NotFound; - // Compare against those previously scheduled operands + // Compare against those previously scheduled nodes unsigned j = i; for (; 0 < j--;) { // Get following instruction - ScheduleInfo *Other = Ordering[j]; + NodeInfo *Other = Ordering[j]; - // Check dependency against previously inserted operands - if (isStrongDependency(Other->Op, SI->Op)) { + // Check dependency against previously inserted nodes + if (isStrongDependency(Other, NI)) { Slot = Other->Slot + Other->Latency; break; - } else if (isWeakDependency(Other->Op, SI->Op)) { + } else if (isWeakDependency(Other, NI)) { Slot = Other->Slot; break; } @@ -622,66 +870,59 @@ if (Slot == NotFound) Slot = 0; // Find a slot where the needed resources are available - if (SI->ResourceSet) - Slot = Tally.FindAndReserve(Slot, SI->Latency, SI->ResourceSet); + if (NI->ResourceSet) + Slot = Tally.FindAndReserve(Slot, NI->Latency, NI->ResourceSet); - // Set operand slot - SI->Slot = Slot; + // Set node slot + NI->Slot = Slot; // Insert sort based on slot j = i; for (; 0 < j--;) { // Get following instruction - ScheduleInfo *Other = Ordering[j]; + NodeInfo *Other = Ordering[j]; // Should we look further if (Slot >= Other->Slot) break; // Shuffle other into ordering Ordering[j + 1] = Other; } - // Insert operand in proper slot - if (j != i) Ordering[j + 1] = SI; + // Insert node in proper slot + if (j != i) Ordering[j + 1] = NI; } } -/// EmitAll - Emit all operands in schedule sorted order. +/// EmitAll - Emit all nodes in schedule sorted order. /// void SimpleSched::EmitAll() { - // For each operand in the ordering + // For each node in the ordering for (unsigned i = 0, N = Ordering.size(); i < N; i++) { // Get the scheduling info - ScheduleInfo *SI = Ordering[i]; - // Get the operand - SDOperand Op = SI->Op; - // Emit the operand - Emit(Op); - // FIXME - PUNT - If Op defines a flag then it's users need to be emitted now - if (isFlagDefiner(Op)) EmitFlagUsers(Op); - } -} - -/// EmitFlagUsers - Emit users of operands flag. -/// -void SimpleSched::EmitFlagUsers(SDOperand Op) { - // Check each flag user - FlagUserIterator FI(Op.Val); - while (SDNode *User = FI.next()) { - // Construct user node as operand - SDOperand OpU(User, 0); - // Emit user node - Emit(OpU); - // If user defines a flag then it's users need to be emitted now - if (isFlagDefiner(User)) EmitFlagUsers(OpU); + NodeInfo *NI = Ordering[i]; +#if 0 + // Iterate through nodes + NodeGroupIterator NGI(Ordering[i]); + while (NodeInfo *NI = NGI.next()) EmitNode(NI); +#else + if (NI->isInGroup()) { + if (NI->isGroupLeader()) { + NodeGroupIterator NGI(Ordering[i]); + while (NodeInfo *NI = NGI.next()) EmitNode(NI); + } + } else { + EmitNode(NI); + } +#endif } } /// CountResults - The results of target nodes have register or immediate /// operands first, then an optional chain, and optional flag operands (which do /// not go into the machine instrs.) -unsigned SimpleSched::CountResults(SDOperand Op) { - unsigned N = Op.Val->getNumValues(); - while (N && Op.Val->getValueType(N - 1) == MVT::Flag) +unsigned SimpleSched::CountResults(SDNode *Node) { + unsigned N = Node->getNumValues(); + while (N && Node->getValueType(N - 1) == MVT::Flag) --N; - if (N && Op.Val->getValueType(N - 1) == MVT::Other) + if (N && Node->getValueType(N - 1) == MVT::Other) --N; // Skip over chain result. return N; } @@ -689,18 +930,18 @@ /// CountOperands The inputs to target nodes have any actual inputs first, /// followed by an optional chain operand, then flag operands. Compute the /// number of actual operands that will go into the machine instr. -unsigned SimpleSched::CountOperands(SDOperand Op) { - unsigned N = Op.getNumOperands(); - while (N && Op.getOperand(N - 1).getValueType() == MVT::Flag) +unsigned SimpleSched::CountOperands(SDNode *Node) { + unsigned N = Node->getNumOperands(); + while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag) --N; - if (N && Op.getOperand(N - 1).getValueType() == MVT::Other) + if (N && Node->getOperand(N - 1).getValueType() == MVT::Other) --N; // Ignore chain if it exists. return N; } /// CreateVirtualRegisters - Add result register values for things that are /// defined by this instruction. -unsigned SimpleSched::CreateVirtualRegisters(SDOperand Op, MachineInstr *MI, +unsigned SimpleSched::CreateVirtualRegisters(MachineInstr *MI, unsigned NumResults, const TargetInstrDescriptor &II) { // Create the result registers for this node and add the result regs to @@ -716,9 +957,131 @@ return ResultReg; } -/// Emit - Generate machine code for an operand and needed dependencies. +/// EmitNode - Generate machine code for an node and needed dependencies. +/// +void SimpleSched::EmitNode(NodeInfo *NI) { + unsigned VRBase = 0; // First virtual register for node + SDNode *Node = NI->Node; + + // If machine instruction + if (Node->isTargetOpcode()) { + unsigned Opc = Node->getTargetOpcode(); + const TargetInstrDescriptor &II = TII.get(Opc); + + unsigned NumResults = CountResults(Node); + unsigned NodeOperands = CountOperands(Node); + unsigned NumMIOperands = NodeOperands + NumResults; +#ifndef NDEBUG + assert((unsigned(II.numOperands) == NumMIOperands || II.numOperands == -1)&& + "#operands for dag node doesn't match .td file!"); +#endif + + // Create the new machine instruction. + MachineInstr *MI = new MachineInstr(Opc, NumMIOperands, true, true); + + // Add result register values for things that are defined by this + // instruction. + if (NumResults) VRBase = CreateVirtualRegisters(MI, NumResults, II); + + // Emit all of the actual operands of this instruction, adding them to the + // instruction as appropriate. + for (unsigned i = 0; i != NodeOperands; ++i) { + if (Node->getOperand(i).isTargetOpcode()) { + // Note that this case is redundant with the final else block, but we + // include it because it is the most common and it makes the logic + // simpler here. + assert(Node->getOperand(i).getValueType() != MVT::Other && + Node->getOperand(i).getValueType() != MVT::Flag && + "Chain and flag operands should occur at end of operand list!"); + + MI->addRegOperand(getVR(Node->getOperand(i)), MachineOperand::Use); + } else if (ConstantSDNode *C = + dyn_cast(Node->getOperand(i))) { + MI->addZeroExtImm64Operand(C->getValue()); + } else if (RegisterSDNode*R = + dyn_cast(Node->getOperand(i))) { + MI->addRegOperand(R->getReg(), MachineOperand::Use); + } else if (GlobalAddressSDNode *TGA = + dyn_cast(Node->getOperand(i))) { + MI->addGlobalAddressOperand(TGA->getGlobal(), false, 0); + } else if (BasicBlockSDNode *BB = + dyn_cast(Node->getOperand(i))) { + MI->addMachineBasicBlockOperand(BB->getBasicBlock()); + } else if (FrameIndexSDNode *FI = + dyn_cast(Node->getOperand(i))) { + MI->addFrameIndexOperand(FI->getIndex()); + } else if (ConstantPoolSDNode *CP = + dyn_cast(Node->getOperand(i))) { + unsigned Idx = ConstPool->getConstantPoolIndex(CP->get()); + MI->addConstantPoolIndexOperand(Idx); + } else if (ExternalSymbolSDNode *ES = + dyn_cast(Node->getOperand(i))) { + MI->addExternalSymbolOperand(ES->getSymbol(), false); + } else { + assert(Node->getOperand(i).getValueType() != MVT::Other && + Node->getOperand(i).getValueType() != MVT::Flag && + "Chain and flag operands should occur at end of operand list!"); + MI->addRegOperand(getVR(Node->getOperand(i)), MachineOperand::Use); + } + } + + // Now that we have emitted all operands, emit this instruction itself. + if ((II.Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION) == 0) { + BB->insert(BB->end(), MI); + } else { + // Insert this instruction into the end of the basic block, potentially + // taking some custom action. + BB = DAG.getTargetLoweringInfo().InsertAtEndOfBasicBlock(MI, BB); + } + } else { + switch (Node->getOpcode()) { + default: + Node->dump(); + assert(0 && "This target-independent node should have been selected!"); + case ISD::EntryToken: // fall thru + case ISD::TokenFactor: + break; + case ISD::CopyToReg: { + unsigned Val = getVR(Node->getOperand(2)); + MRI.copyRegToReg(*BB, BB->end(), + cast(Node->getOperand(1))->getReg(), Val, + RegMap->getRegClass(Val)); + break; + } + case ISD::CopyFromReg: { + unsigned SrcReg = cast(Node->getOperand(1))->getReg(); + + // Figure out the register class to create for the destreg. + const TargetRegisterClass *TRC = 0; + if (MRegisterInfo::isVirtualRegister(SrcReg)) { + TRC = RegMap->getRegClass(SrcReg); + } else { + // FIXME: we don't know what register class to generate this for. Do + // a brute force search and pick the first match. :( + for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(), + E = MRI.regclass_end(); I != E; ++I) + if ((*I)->contains(SrcReg)) { + TRC = *I; + break; + } + assert(TRC && "Couldn't find register class for reg copy!"); + } + + // Create the reg, emit the copy. + VRBase = RegMap->createVirtualRegister(TRC); + MRI.copyRegToReg(*BB, BB->end(), VRBase, SrcReg, TRC); + break; + } + } + } + + assert(NI->VRBase == 0 && "Node emitted out of order - early"); + NI->VRBase = VRBase; +} + +/// EmitDag - Generate machine code for an operand and needed dependencies. /// -unsigned SimpleSched::Emit(SDOperand Op) { +unsigned SimpleSched::EmitDAG(SDOperand Op) { std::map::iterator OpI = VRMap.lower_bound(Op.Val); if (OpI != VRMap.end() && OpI->first == Op.Val) return OpI->second + Op.ResNo; @@ -729,8 +1092,8 @@ unsigned Opc = Op.getTargetOpcode(); const TargetInstrDescriptor &II = TII.get(Opc); - unsigned NumResults = CountResults(Op); - unsigned NodeOperands = CountOperands(Op); + unsigned NumResults = CountResults(Op.Val); + unsigned NodeOperands = CountOperands(Op.Val); unsigned NumMIOperands = NodeOperands + NumResults; #ifndef NDEBUG assert((unsigned(II.numOperands) == NumMIOperands || II.numOperands == -1)&& @@ -742,13 +1105,13 @@ // Add result register values for things that are defined by this // instruction. - if (NumResults) ResultReg = CreateVirtualRegisters(Op, MI, NumResults, II); + if (NumResults) ResultReg = CreateVirtualRegisters(MI, NumResults, II); // If there is a token chain operand, emit it first, as a hack to get avoid // really bad cases. if (Op.getNumOperands() > NodeOperands && Op.getOperand(NodeOperands).getValueType() == MVT::Other) { - Emit(Op.getOperand(NodeOperands)); + EmitDAG(Op.getOperand(NodeOperands)); } // Emit all of the actual operands of this instruction, adding them to the @@ -762,7 +1125,7 @@ Op.getOperand(i).getValueType() != MVT::Flag && "Chain and flag operands should occur at end of operand list!"); - MI->addRegOperand(Emit(Op.getOperand(i)), MachineOperand::Use); + MI->addRegOperand(EmitDAG(Op.getOperand(i)), MachineOperand::Use); } else if (ConstantSDNode *C = dyn_cast(Op.getOperand(i))) { MI->addZeroExtImm64Operand(C->getValue()); @@ -788,7 +1151,7 @@ assert(Op.getOperand(i).getValueType() != MVT::Other && Op.getOperand(i).getValueType() != MVT::Flag && "Chain and flag operands should occur at end of operand list!"); - MI->addRegOperand(Emit(Op.getOperand(i)), MachineOperand::Use); + MI->addRegOperand(EmitDAG(Op.getOperand(i)), MachineOperand::Use); } } @@ -801,7 +1164,7 @@ for (unsigned N = Op.getNumOperands(); i < N; i++) { assert(Op.getOperand(i).getValueType() == MVT::Flag && "Must be flag operands!"); - Emit(Op.getOperand(i)); + EmitDAG(Op.getOperand(i)); } } @@ -821,7 +1184,7 @@ case ISD::EntryToken: break; case ISD::TokenFactor: for (unsigned i = 0, N = Op.getNumOperands(); i < N; i++) { - Emit(Op.getOperand(i)); + EmitDAG(Op.getOperand(i)); } break; case ISD::CopyToReg: { @@ -830,11 +1193,11 @@ FlagOp = Op.getOperand(3); } if (Op.getOperand(0).Val != FlagOp.Val) { - Emit(Op.getOperand(0)); // Emit the chain. + EmitDAG(Op.getOperand(0)); // Emit the chain. } - unsigned Val = Emit(Op.getOperand(2)); + unsigned Val = EmitDAG(Op.getOperand(2)); if (FlagOp.Val) { - Emit(FlagOp); + EmitDAG(FlagOp); } MRI.copyRegToReg(*BB, BB->end(), cast(Op.getOperand(1))->getReg(), Val, @@ -842,7 +1205,7 @@ break; } case ISD::CopyFromReg: { - Emit(Op.getOperand(0)); // Emit the chain. + EmitDAG(Op.getOperand(0)); // Emit the chain. unsigned SrcReg = cast(Op.getOperand(1))->getReg(); // Figure out the register class to create for the destreg. @@ -873,17 +1236,19 @@ return ResultReg+Op.ResNo; } -/// Schedule - Order operands according to selected style. +/// Schedule - Order nodes according to selected style. /// void SimpleSched::Schedule() { switch (ScheduleStyle) { case simpleScheduling: - // Breadth first walk of DAG - VisitAll(); - // Get latency and resource requirements - GatherOperandInfo(); + // Number the nodes + NodeCount = DAG.allnodes_size(); // Don't waste time if is only entry and return - if (Operands.size() > 2) { + if (NodeCount > 3) { + // Get latency and resource requirements + GatherNodeInfo(); + // Breadth first walk of DAG + VisitAll(); DEBUG(dump("Pre-")); // Push back long instructions and critical path ScheduleBackward(); @@ -897,27 +1262,27 @@ } // fall thru case noScheduling: // Emit instructions in using a DFS from the exit root - Emit(DAG.getRoot()); + EmitDAG(DAG.getRoot()); break; } } /// printSI - Print schedule info. /// -void SimpleSched::printSI(std::ostream &O, ScheduleInfo *SI) const { +void SimpleSched::printSI(std::ostream &O, NodeInfo *NI) const { #ifndef NDEBUG using namespace std; - SDOperand Op = SI->Op; + SDNode *Node = NI->Node; O << " " - << hex << Op.Val - << ", RS=" << SI->ResourceSet - << ", Lat=" << SI->Latency - << ", Slot=" << SI->Slot - << ", ARITY=(" << Op.getNumOperands() << "," - << Op.Val->getNumValues() << ")" - << " " << Op.Val->getOperationName(&DAG); - if (isFlagDefiner(Op)) O << "<#"; - if (isFlagUser(Op)) O << ">#"; + << hex << Node + << ", RS=" << NI->ResourceSet + << ", Lat=" << NI->Latency + << ", Slot=" << NI->Slot + << ", ARITY=(" << Node->getNumOperands() << "," + << Node->getNumValues() << ")" + << " " << Node->getOperationName(&DAG); + if (isFlagDefiner(Node)) O << "<#"; + if (isFlagUser(Node)) O << ">#"; #endif } From jlaskey at apple.com Fri Sep 30 14:27:13 2005 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 30 Sep 2005 14:27:13 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200509301927.OAA27078@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.61 -> 1.62 --- Log message: Added allnodes_size for scheduling support. --- Diffs of the changes: (+1 -0) SelectionDAG.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.61 llvm/include/llvm/CodeGen/SelectionDAG.h:1.62 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.61 Wed Sep 7 00:36:18 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Fri Sep 30 14:27:01 2005 @@ -66,6 +66,7 @@ typedef std::vector::const_iterator allnodes_iterator; allnodes_iterator allnodes_begin() const { return AllNodes.begin(); } allnodes_iterator allnodes_end() const { return AllNodes.end(); } + unsigned allnodes_size() const { return AllNodes.size(); } /// getRoot - Return the root tag of the SelectionDAG. /// From jlaskey at apple.com Fri Sep 30 14:33:53 2005 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 30 Sep 2005 14:33:53 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/GraphWriter.h Message-ID: <200509301933.OAA27249@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: GraphWriter.h updated: 1.24 -> 1.25 --- Log message: Reverting change moving to selection dag graph. --- Diffs of the changes: (+1 -1) GraphWriter.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Support/GraphWriter.h diff -u llvm/include/llvm/Support/GraphWriter.h:1.24 llvm/include/llvm/Support/GraphWriter.h:1.25 --- llvm/include/llvm/Support/GraphWriter.h:1.24 Fri Sep 30 14:11:53 2005 +++ llvm/include/llvm/Support/GraphWriter.h Fri Sep 30 14:33:41 2005 @@ -134,7 +134,7 @@ if (DOTTraits::renderGraphFromBottomUp()) O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G)); - O << "|\\N}\"];\n"; // Finish printing the "node" line + O << "}\"];\n"; // Finish printing the "node" line // Output all of the edges now EI = GTraits::child_begin(Node); From alenhar2 at cs.uiuc.edu Fri Sep 30 15:24:49 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Fri, 30 Sep 2005 15:24:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaSubtarget.cpp Message-ID: <200509302024.PAA27726@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaSubtarget.cpp updated: 1.1 -> 1.2 --- Log message: subtarget support for CIX and FIX extentions (the only 2 I care about right now) --- Diffs of the changes: (+35 -2) AlphaSubtarget.cpp | 37 +++++++++++++++++++++++++++++++++++-- 1 files changed, 35 insertions(+), 2 deletions(-) Index: llvm/lib/Target/Alpha/AlphaSubtarget.cpp diff -u llvm/lib/Target/Alpha/AlphaSubtarget.cpp:1.1 llvm/lib/Target/Alpha/AlphaSubtarget.cpp:1.2 --- llvm/lib/Target/Alpha/AlphaSubtarget.cpp:1.1 Thu Sep 29 17:54:56 2005 +++ llvm/lib/Target/Alpha/AlphaSubtarget.cpp Fri Sep 30 15:24:38 2005 @@ -16,13 +16,46 @@ #include "llvm/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Target/SubtargetFeature.h" +#include "llvm/Support/Debug.h" using namespace llvm; -//"alphaev67-unknown-linux-gnu" +enum AlphaFeature { + AlphaFeatureCIX = 1 << 0, + AlphaFeatureFIX = 1 << 1, +}; + +/// Sorted (by key) array of values for CPU subtype. +static const SubtargetFeatureKV AlphaSubTypeKV[] = { + { "ev56" , "Select the Alpha EV56 processor", 0 }, + { "ev6" , "Select the Alpha EV6 processor", AlphaFeatureFIX }, + { "ev67" , "Select the Alpha EV67 processor", AlphaFeatureFIX | AlphaFeatureCIX }, + { "pca56" , "Select the Alpha PCA56 processor", 0 }, + { "generic", "Select instructions for a generic Alpha processor (EV56)", 0 } +}; + +/// Length of AlphaSubTypeKV. +static const unsigned AlphaSubTypeKVSize = sizeof(AlphaSubTypeKV) + / sizeof(SubtargetFeatureKV); + +/// Sorted (by key) array of values for CPU features. +static SubtargetFeatureKV AlphaFeatureKV[] = { + { "FIX" , "Should FIX extentions be used" , AlphaFeatureFIX }, + { "CIX", "Should CIX extentions be used" , AlphaFeatureCIX } + }; +/// Length of AlphaFeatureKV. +static const unsigned AlphaFeatureKVSize = sizeof(AlphaFeatureKV) + / sizeof(SubtargetFeatureKV); AlphaSubtarget::AlphaSubtarget(const Module &M, const std::string &FS) :HasF2I(false), HasCT(false) { -//TODO: figure out host + std::string CPU = "generic"; + uint32_t Bits = + SubtargetFeatures::Parse(FS, CPU, + AlphaSubTypeKV, AlphaSubTypeKVSize, + AlphaFeatureKV, AlphaFeatureKVSize); + HasF2I = (Bits & AlphaFeatureFIX) != 0; + HasCT = (Bits & AlphaFeatureCIX) != 0; + } From alenhar2 at cs.uiuc.edu Fri Sep 30 15:30:36 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Fri, 30 Sep 2005 15:30:36 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Alpha/ctlz.ll ctpop.ll Message-ID: <200509302030.PAA28017@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Alpha: ctlz.ll updated: 1.4 -> 1.5 ctpop.ll updated: 1.5 -> 1.6 --- Log message: more specific tests of subtarget stuff --- Diffs of the changes: (+11 -2) ctlz.ll | 6 +++++- ctpop.ll | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) Index: llvm/test/Regression/CodeGen/Alpha/ctlz.ll diff -u llvm/test/Regression/CodeGen/Alpha/ctlz.ll:1.4 llvm/test/Regression/CodeGen/Alpha/ctlz.ll:1.5 --- llvm/test/Regression/CodeGen/Alpha/ctlz.ll:1.4 Fri May 13 14:49:01 2005 +++ llvm/test/Regression/CodeGen/Alpha/ctlz.ll Fri Sep 30 15:30:24 2005 @@ -1,5 +1,9 @@ ; Make sure this testcase codegens to the ctlz instruction -; RUN: llvm-as < %s | llc -march=alpha -enable-alpha-CT | grep -i 'ctlz' +; RUN: llvm-as < %s | llc -march=alpha -mcpu=ev67 | grep -i 'ctlz' +; RUN: llvm-as < %s | llc -march=alpha -mattr=+CIX | grep -i 'ctlz' +; RUN: llvm-as < %s | llc -march=alpha -mcpu=ev6 | not grep -i 'ctlz' +; RUN: llvm-as < %s | llc -march=alpha -mcpu=ev56 | not grep -i 'ctlz' +; RUN: llvm-as < %s | llc -march=alpha -mattr=-CIX | not grep -i 'ctlz' declare ubyte %llvm.ctlz(ubyte) Index: llvm/test/Regression/CodeGen/Alpha/ctpop.ll diff -u llvm/test/Regression/CodeGen/Alpha/ctpop.ll:1.5 llvm/test/Regression/CodeGen/Alpha/ctpop.ll:1.6 --- llvm/test/Regression/CodeGen/Alpha/ctpop.ll:1.5 Fri May 13 21:35:38 2005 +++ llvm/test/Regression/CodeGen/Alpha/ctpop.ll Fri Sep 30 15:30:24 2005 @@ -1,5 +1,10 @@ ; Make sure this testcase codegens to the ctpop instruction -; RUN: llvm-as < %s | llc -march=alpha -enable-alpha-CT | grep -i 'ctpop' +; RUN: llvm-as < %s | llc -march=alpha -mcpu=ev67 | grep -i 'ctpop' +; RUN: llvm-as < %s | llc -march=alpha -mattr=+CIX | grep -i 'ctpop' +; RUN: llvm-as < %s | llc -march=alpha -mcpu=ev6 | not grep -i 'ctpop' +; RUN: llvm-as < %s | llc -march=alpha -mcpu=ev56 | not grep -i 'ctpop' +; RUN: llvm-as < %s | llc -march=alpha -mattr=-CIX | not grep -i 'ctpop' + declare long %llvm.ctpop(long) From natebegeman at mac.com Fri Sep 30 16:28:38 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 30 Sep 2005 16:28:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Message-ID: <200509302128.QAA28982@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32RegisterInfo.cpp updated: 1.26 -> 1.27 --- Log message: Remove some now-dead code. --- Diffs of the changes: (+4 -15) PPC32RegisterInfo.cpp | 19 ++++--------------- 1 files changed, 4 insertions(+), 15 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.26 llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.27 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.26 Fri Sep 30 12:16:59 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Fri Sep 30 16:28:27 2005 @@ -43,15 +43,6 @@ ImmToIdxMap[PPC::ADDI] = PPC::ADD; } -static const TargetRegisterClass *getClass(unsigned SrcReg) { - if (PPC32::GPRCRegisterClass->contains(SrcReg)) - return PPC32::GPRCRegisterClass; - if (PPC32::FPRCRegisterClass->contains(SrcReg)) - return PPC32::FPRCRegisterClass; - assert(PPC32::CRRCRegisterClass->contains(SrcReg) &&"Reg not FPR, GPR, CRRC"); - return PPC32::CRRCRegisterClass; -} - static unsigned getIdx(const TargetRegisterClass *RC) { if (RC == PPC32::GPRCRegisterClass) { switch (RC->getSize()) { @@ -84,12 +75,11 @@ static const unsigned Opcode[] = { PPC::STB, PPC::STH, PPC::STW, PPC::STFS, PPC::STFD }; - const TargetRegisterClass *RegClass = getClass(SrcReg); - unsigned OC = Opcode[getIdx(RegClass)]; + unsigned OC = Opcode[getIdx(RC)]; if (SrcReg == PPC::LR) { BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11); addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx); - } else if (RegClass == PPC32::CRRCRegisterClass) { + } else if (RC == PPC32::CRRCRegisterClass) { BuildMI(MBB, MI, PPC::MFCR, 0, PPC::R11); addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx); } else { @@ -105,12 +95,11 @@ static const unsigned Opcode[] = { PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LFS, PPC::LFD }; - const TargetRegisterClass *RegClass = getClass(DestReg); - unsigned OC = Opcode[getIdx(RegClass)]; + unsigned OC = Opcode[getIdx(RC)]; if (DestReg == PPC::LR) { addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx); BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11); - } else if (RegClass == PPC32::CRRCRegisterClass) { + } else if (RC == PPC32::CRRCRegisterClass) { addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx); BuildMI(MBB, MI, PPC::MTCRF, 1, DestReg).addReg(PPC::R11); } else { From jlaskey at apple.com Fri Sep 30 18:43:49 2005 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 30 Sep 2005 18:43:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509302343.SAA32261@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.87 -> 1.88 --- Log message: Should be using flag and not chain. --- Diffs of the changes: (+1 -1) PPC32ISelDAGToDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.87 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.88 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.87 Thu Sep 29 18:33:31 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Fri Sep 30 18:43:37 2005 @@ -1351,7 +1351,7 @@ Chain.getValue(1)).getValue(1); CallResults.push_back(Chain.getValue(0)); Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, - Chain.getValue(1)).getValue(1); + Chain.getValue(2)).getValue(1); CallResults.push_back(Chain.getValue(0)); } else { Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, From jlaskey at apple.com Fri Sep 30 19:03:19 2005 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 30 Sep 2005 19:03:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200510010003.TAA00306@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.26 -> 1.27 --- Log message: 1. Simplify the gathering of node groups. 2. Printing node groups when displaying nodes. --- Diffs of the changes: (+22 -54) ScheduleDAG.cpp | 76 ++++++++++++++++---------------------------------------- 1 files changed, 22 insertions(+), 54 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.26 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.27 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.26 Fri Sep 30 14:15:27 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Sep 30 19:03:07 2005 @@ -448,56 +448,8 @@ }; //===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -class FlagUserIterator { -private: - SDNode *Definer; // Node defining flag - SDNode::use_iterator UI; // User node iterator - SDNode::use_iterator E; // End of user nodes - unsigned MinRes; // Minimum flag result - -public: - // Ctor. - FlagUserIterator(SDNode *D) - : Definer(D) - , UI(D->use_begin()) - , E(D->use_end()) - , MinRes(D->getNumValues()) { - // Find minimum flag result. - while (MinRes && D->getValueType(MinRes - 1) == MVT::Flag) --MinRes; - } - - /// isFlagUser - Return true if node uses definer's flag. - bool isFlagUser(SDNode *U) { - // For each operand (in reverse to only look at flags) - for (unsigned N = U->getNumOperands(); 0 < N--;) { - // Get operand - SDOperand Op = U->getOperand(N); - // Not user if there are no flags - if (Op.getValueType() != MVT::Flag) return false; - // Return true if it is one of the flag results - if (Op.Val == Definer && Op.ResNo >= MinRes) return true; - } - // Not a flag user - return false; - } - - SDNode *next() { - // Continue to next user - while (UI != E) { - // Next user node - SDNode *User = *UI++; - // Return true if is a flag user - if (isFlagUser(User)) return User; - } - - // No more user nodes - return NULL; - } -}; - } // namespace + //===----------------------------------------------------------------------===// @@ -749,14 +701,20 @@ // Sum up all the latencies for max tally size NSlots += NI->Latency; } - + // Put flagged nodes into groups for (unsigned i = 0, N = NodeCount; i < N; i++) { NodeInfo* NI = &Info[i]; SDNode *Node = NI->Node; - if (isFlagDefiner(Node)) { - FlagUserIterator FI(Node); - while (SDNode *User = FI.next()) NodeGroup::Add(NI, getNI(User)); + + // For each operand (in reverse to only look at flags) + for (unsigned N = Node->getNumOperands(); 0 < N--;) { + // Get operand + SDOperand Op = Node->getOperand(N); + // No more flags to walk + if (Op.getValueType() != MVT::Flag) break; + // Add do node group + NodeGroup::Add(getNI(Op.Val), NI); } } } @@ -1293,8 +1251,18 @@ using namespace std; O << "Ordering\n"; for (unsigned i = 0, N = Ordering.size(); i < N; i++) { - printSI(O, Ordering[i]); + NodeInfo *NI = Ordering[i]; + printSI(O, NI); O << "\n"; + if (NI->isGroupLeader()) { + NodeGroup *Group = NI->Group; + for (NIIterator NII = Group->begin(), E = Group->end(); + NII != E; NII++) { + O << " "; + printSI(O, *NII); + O << "\n"; + } + } } #endif } From jlaskey at apple.com Fri Sep 30 19:08:34 2005 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 30 Sep 2005 19:08:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200510010008.TAA00329@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.27 -> 1.28 --- Log message: typo --- Diffs of the changes: (+1 -1) ScheduleDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.27 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.28 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.27 Fri Sep 30 19:03:07 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Sep 30 19:08:23 2005 @@ -713,7 +713,7 @@ SDOperand Op = Node->getOperand(N); // No more flags to walk if (Op.getValueType() != MVT::Flag) break; - // Add do node group + // Add to node group NodeGroup::Add(getNI(Op.Val), NI); } } From lattner at cs.uiuc.edu Fri Sep 30 19:15:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 19:15:23 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Message-ID: <200510010015.TAA00380@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGPrinter.cpp updated: 1.24 -> 1.25 --- Log message: add a method --- Diffs of the changes: (+5 -0) SelectionDAGPrinter.cpp | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.24 llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.25 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.24 Fri Aug 26 12:14:58 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Fri Sep 30 19:15:11 2005 @@ -33,6 +33,11 @@ static bool renderGraphFromBottomUp() { return true; } + + static bool hasNodeAddressLabel(const SDNode *Node, + const SelectionDAG *Graph) { + return true; + } static std::string getNodeLabel(const SDNode *Node, const SelectionDAG *Graph); From lattner at cs.uiuc.edu Fri Sep 30 19:17:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 19:17:19 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/DOTGraphTraits.h Message-ID: <200510010017.TAA00439@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: DOTGraphTraits.h updated: 1.13 -> 1.14 --- Log message: add a method --- Diffs of the changes: (+6 -0) DOTGraphTraits.h | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/include/llvm/Support/DOTGraphTraits.h diff -u llvm/include/llvm/Support/DOTGraphTraits.h:1.13 llvm/include/llvm/Support/DOTGraphTraits.h:1.14 --- llvm/include/llvm/Support/DOTGraphTraits.h:1.13 Thu Apr 21 15:44:59 2005 +++ llvm/include/llvm/Support/DOTGraphTraits.h Fri Sep 30 19:17:07 2005 @@ -51,6 +51,12 @@ static std::string getNodeLabel(const void *Node, const void *Graph) { return ""; } + + /// hasNodeAddressLabel - If this method returns true, the address of the node + /// is added to the label of the node. + static bool hasNodeAddressLabel(const void *Node, const void *Graph) { + return false; + } /// If you want to specify custom node attributes, this is the place to do so /// From lattner at cs.uiuc.edu Fri Sep 30 19:19:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 19:19:32 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/GraphWriter.h Message-ID: <200510010019.TAA00546@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: GraphWriter.h updated: 1.25 -> 1.26 --- Log message: Annotate nodes with their addresses if a graph requests it. This is Jim's feature implemented so that graphs could 'opt-in' and get this behavior. This is currently used by selection dags. --- Diffs of the changes: (+13 -2) GraphWriter.h | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Support/GraphWriter.h diff -u llvm/include/llvm/Support/GraphWriter.h:1.25 llvm/include/llvm/Support/GraphWriter.h:1.26 --- llvm/include/llvm/Support/GraphWriter.h:1.25 Fri Sep 30 14:33:41 2005 +++ llvm/include/llvm/Support/GraphWriter.h Fri Sep 30 19:19:21 2005 @@ -111,9 +111,14 @@ if (!NodeAttributes.empty()) O << NodeAttributes << ","; O << "label=\"{"; - if (!DOTTraits::renderGraphFromBottomUp()) + if (!DOTTraits::renderGraphFromBottomUp()) { O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G)); + // If we should include the address of the node in the label, do so now. + if (DOTTraits::hasNodeAddressLabel(Node, G)) + O << "|" << (void*)Node; + } + // Print out the fields of the current node... child_iterator EI = GTraits::child_begin(Node); child_iterator EE = GTraits::child_end(Node); @@ -131,9 +136,15 @@ O << "}"; if (DOTTraits::renderGraphFromBottomUp()) O << "|"; } - if (DOTTraits::renderGraphFromBottomUp()) + + if (DOTTraits::renderGraphFromBottomUp()) { O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G)); + // If we should include the address of the node in the label, do so now. + if (DOTTraits::hasNodeAddressLabel(Node, G)) + O << "|" << (void*)Node; + } + O << "}\"];\n"; // Finish printing the "node" line // Output all of the edges now From lattner at cs.uiuc.edu Fri Sep 30 20:34:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 20:34:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td PowerPCBranchSelector.cpp PPC32RegisterInfo.td PPC32RegisterInfo.cpp PPC32InstrInfo.cpp Message-ID: <200510010134.UAA01135@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.114 -> 1.115 PowerPCBranchSelector.cpp updated: 1.14 -> 1.15 PPC32RegisterInfo.td updated: 1.7 -> 1.8 PPC32RegisterInfo.cpp updated: 1.27 -> 1.28 PPC32InstrInfo.cpp updated: 1.5 -> 1.6 --- Log message: Modify the ppc backend to use two register classes for FP: F8RC and F4RC. These are used to represent float and double values, and the two regclasses contain the same physical registers. --- Diffs of the changes: (+140 -108) PPC32InstrInfo.cpp | 2 PPC32RegisterInfo.cpp | 82 +++++++++++------------- PPC32RegisterInfo.td | 6 + PowerPCBranchSelector.cpp | 3 PowerPCInstrInfo.td | 155 +++++++++++++++++++++++++++------------------- 5 files changed, 140 insertions(+), 108 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.114 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.115 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.114 Thu Sep 29 18:34:24 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Fri Sep 30 20:34:18 2005 @@ -317,14 +317,17 @@ def ADJCALLSTACKUP : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKUP">; } def IMPLICIT_DEF_GPR : Pseudo<(ops GPRC:$rD), "; $rD = IMPLICIT_DEF_GPRC">; -def IMPLICIT_DEF_FP : Pseudo<(ops FPRC:$rD), "; %rD = IMPLICIT_DEF_FP">; +def IMPLICIT_DEF_F8 : Pseudo<(ops F8RC:$rD), "; %rD = IMPLICIT_DEF_F8">; +def IMPLICIT_DEF_F4 : Pseudo<(ops F4RC:$rD), "; %rD = IMPLICIT_DEF_F4">; // SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded by the // scheduler into a branch sequence. let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. def SELECT_CC_Int : Pseudo<(ops GPRC:$dst, CRRC:$cond, GPRC:$T, GPRC:$F, i32imm:$BROPC), "; SELECT_CC PSEUDO!">; - def SELECT_CC_FP : Pseudo<(ops FPRC:$dst, CRRC:$cond, FPRC:$T, FPRC:$F, + def SELECT_CC_F4 : Pseudo<(ops F4RC:$dst, CRRC:$cond, F4RC:$T, F4RC:$F, + i32imm:$BROPC), "; SELECT_CC PSEUDO!">; + def SELECT_CC_F8 : Pseudo<(ops F8RC:$dst, CRRC:$cond, F8RC:$T, F8RC:$F, i32imm:$BROPC), "; SELECT_CC PSEUDO!">; } @@ -463,15 +466,15 @@ def CMPLDI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2), "cmpldi $dst, $src1, $src2">, isPPC64; let isLoad = 1 in { -def LFS : DForm_8<48, (ops FPRC:$rD, symbolLo:$disp, GPRC:$rA), +def LFS : DForm_8<48, (ops F4RC:$rD, symbolLo:$disp, GPRC:$rA), "lfs $rD, $disp($rA)">; -def LFD : DForm_8<50, (ops FPRC:$rD, symbolLo:$disp, GPRC:$rA), +def LFD : DForm_8<50, (ops F8RC:$rD, symbolLo:$disp, GPRC:$rA), "lfd $rD, $disp($rA)">; } let isStore = 1 in { -def STFS : DForm_9<52, (ops FPRC:$rS, symbolLo:$disp, GPRC:$rA), +def STFS : DForm_9<52, (ops F4RC:$rS, symbolLo:$disp, GPRC:$rA), "stfs $rS, $disp($rA)">; -def STFD : DForm_9<54, (ops FPRC:$rS, symbolLo:$disp, GPRC:$rA), +def STFD : DForm_9<54, (ops F8RC:$rS, symbolLo:$disp, GPRC:$rA), "stfd $rS, $disp($rA)">; } @@ -596,51 +599,74 @@ "cmplw $crD, $rA, $rB">; def CMPLD : XForm_16_ext<31, 32, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB), "cmpld $crD, $rA, $rB">, isPPC64; -def FCMPO : XForm_17<63, 32, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB), - "fcmpo $crD, $fA, $fB">; -def FCMPU : XForm_17<63, 0, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB), +//def FCMPO : XForm_17<63, 32, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB), +// "fcmpo $crD, $fA, $fB">; +def FCMPUS : XForm_17<63, 0, (ops CRRC:$crD, F4RC:$fA, F4RC:$fB), + "fcmpu $crD, $fA, $fB">; +def FCMPUD : XForm_17<63, 0, (ops CRRC:$crD, F8RC:$fA, F8RC:$fB), "fcmpu $crD, $fA, $fB">; + let isLoad = 1 in { -def LFSX : XForm_25<31, 535, (ops FPRC:$dst, GPRC:$base, GPRC:$index), +def LFSX : XForm_25<31, 535, (ops F4RC:$dst, GPRC:$base, GPRC:$index), "lfsx $dst, $base, $index">; -def LFDX : XForm_25<31, 599, (ops FPRC:$dst, GPRC:$base, GPRC:$index), +def LFDX : XForm_25<31, 599, (ops F8RC:$dst, GPRC:$base, GPRC:$index), "lfdx $dst, $base, $index">; } -def FCFID : XForm_26<63, 846, (ops FPRC:$frD, FPRC:$frB), +def FCFID : XForm_26<63, 846, (ops F8RC:$frD, F8RC:$frB), "fcfid $frD, $frB", []>, isPPC64; -def FCTIDZ : XForm_26<63, 815, (ops FPRC:$frD, FPRC:$frB), +def FCTIDZ : XForm_26<63, 815, (ops F8RC:$frD, F8RC:$frB), "fctidz $frD, $frB", []>, isPPC64; -def FCTIWZ : XForm_26<63, 15, (ops FPRC:$frD, FPRC:$frB), +def FCTIWZ : XForm_26<63, 15, (ops F8RC:$frD, F8RC:$frB), "fctiwz $frD, $frB", []>; -def FABS : XForm_26<63, 264, (ops FPRC:$frD, FPRC:$frB), - "fabs $frD, $frB", - [(set FPRC:$frD, (fabs FPRC:$frB))]>; -def FMR : XForm_26<63, 72, (ops FPRC:$frD, FPRC:$frB), - "fmr $frD, $frB", - []>; // (set FPRC:$frD, FPRC:$frB) -def FNABS : XForm_26<63, 136, (ops FPRC:$frD, FPRC:$frB), - "fnabs $frD, $frB", - [(set FPRC:$frD, (fneg (fabs FPRC:$frB)))]>; -def FNEG : XForm_26<63, 40, (ops FPRC:$frD, FPRC:$frB), - "fneg $frD, $frB", - [(set FPRC:$frD, (fneg FPRC:$frB))]>; -def FRSP : XForm_26<63, 12, (ops FPRC:$frD, FPRC:$frB), +def FRSP : XForm_26<63, 12, (ops F4RC:$frD, F8RC:$frB), "frsp $frD, $frB", []>; -def FSQRT : XForm_26<63, 22, (ops FPRC:$frD, FPRC:$frB), +def FSQRT : XForm_26<63, 22, (ops F8RC:$frD, F8RC:$frB), "fsqrt $frD, $frB", - [(set FPRC:$frD, (fsqrt FPRC:$frB))]>; -def FSQRTS : XForm_26<59, 22, (ops FPRC:$frD, FPRC:$frB), + [(set F8RC:$frD, (fsqrt F8RC:$frB))]>; +def FSQRTS : XForm_26<59, 22, (ops F4RC:$frD, F4RC:$frB), "fsqrts $frD, $frB", []>; + +/// FMR is split into 3 versions, one for 4/8 byte FP, and one for extending. +def FMRS : XForm_26<63, 72, (ops F4RC:$frD, F4RC:$frB), + "fmr $frD, $frB", + []>; // (set F4RC:$frD, F4RC:$frB) +def FMRD : XForm_26<63, 72, (ops F8RC:$frD, F8RC:$frB), + "fmr $frD, $frB", + []>; // (set F8RC:$frD, F8RC:$frB) +def FMRSD : XForm_26<63, 72, (ops F8RC:$frD, F4RC:$frB), + "fmr $frD, $frB", + []>; // (set F8RC:$frD, (fpextend F4RC:$frB)) + +// These are artificially split into two different forms, for 4/8 byte FP. +def FABSS : XForm_26<63, 264, (ops F4RC:$frD, F4RC:$frB), + "fabs $frD, $frB", + [(set F4RC:$frD, (fabs F4RC:$frB))]>; +def FABSD : XForm_26<63, 264, (ops F8RC:$frD, F8RC:$frB), + "fabs $frD, $frB", + [(set F8RC:$frD, (fabs F8RC:$frB))]>; +def FNABSS : XForm_26<63, 136, (ops F4RC:$frD, F4RC:$frB), + "fnabs $frD, $frB", + [(set F4RC:$frD, (fneg (fabs F4RC:$frB)))]>; +def FNABSD : XForm_26<63, 136, (ops F8RC:$frD, F8RC:$frB), + "fnabs $frD, $frB", + [(set F8RC:$frD, (fneg (fabs F8RC:$frB)))]>; +def FNEGS : XForm_26<63, 40, (ops F4RC:$frD, F4RC:$frB), + "fneg $frD, $frB", + [(set F4RC:$frD, (fneg F4RC:$frB))]>; +def FNEGD : XForm_26<63, 40, (ops F8RC:$frD, F8RC:$frB), + "fneg $frD, $frB", + [(set F8RC:$frD, (fneg F8RC:$frB))]>; + let isStore = 1 in { -def STFSX : XForm_28<31, 663, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB), +def STFSX : XForm_28<31, 663, (ops F4RC:$frS, GPRC:$rA, GPRC:$rB), "stfsx $frS, $rA, $rB">; -def STFDX : XForm_28<31, 727, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB), +def STFDX : XForm_28<31, 727, (ops F8RC:$frS, GPRC:$rA, GPRC:$rB), "stfdx $frS, $rA, $rB">; } @@ -730,75 +756,80 @@ // this type. // def FMADD : AForm_1<63, 29, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), "fmadd $FRT, $FRA, $FRC, $FRB", - [(set FPRC:$FRT, (fadd (fmul FPRC:$FRA, FPRC:$FRC), - FPRC:$FRB))]>; + [(set F8RC:$FRT, (fadd (fmul F8RC:$FRA, F8RC:$FRC), + F8RC:$FRB))]>; def FMADDS : AForm_1<59, 29, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), "fmadds $FRT, $FRA, $FRC, $FRB", []>; def FMSUB : AForm_1<63, 28, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), "fmsub $FRT, $FRA, $FRC, $FRB", - [(set FPRC:$FRT, (fsub (fmul FPRC:$FRA, FPRC:$FRC), - FPRC:$FRB))]>; + [(set F8RC:$FRT, (fsub (fmul F8RC:$FRA, F8RC:$FRC), + F8RC:$FRB))]>; def FMSUBS : AForm_1<59, 28, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), "fmsubs $FRT, $FRA, $FRC, $FRB", []>; def FNMADD : AForm_1<63, 31, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), "fnmadd $FRT, $FRA, $FRC, $FRB", - [(set FPRC:$FRT, (fneg (fadd (fmul FPRC:$FRA, FPRC:$FRC), - FPRC:$FRB)))]>; + [(set F8RC:$FRT, (fneg (fadd (fmul F8RC:$FRA, F8RC:$FRC), + F8RC:$FRB)))]>; def FNMADDS : AForm_1<59, 31, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), "fnmadds $FRT, $FRA, $FRC, $FRB", []>; def FNMSUB : AForm_1<63, 30, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), "fnmsub $FRT, $FRA, $FRC, $FRB", - [(set FPRC:$FRT, (fneg (fsub (fmul FPRC:$FRA, FPRC:$FRC), - FPRC:$FRB)))]>; + [(set F8RC:$FRT, (fneg (fsub (fmul F8RC:$FRA, F8RC:$FRC), + F8RC:$FRB)))]>; def FNMSUBS : AForm_1<59, 30, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), "fnmsubs $FRT, $FRA, $FRC, $FRB", []>; -def FSEL : AForm_1<63, 23, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), +// FSEL is artificially split into 4 and 8-byte forms. +def FSELD : AForm_1<63, 23, + (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), + "fsel $FRT, $FRA, $FRC, $FRB", + []>; +def FSELS : AForm_1<63, 23, + (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), "fsel $FRT, $FRA, $FRC, $FRB", []>; def FADD : AForm_2<63, 21, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), + (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB), "fadd $FRT, $FRA, $FRB", - [(set FPRC:$FRT, (fadd FPRC:$FRA, FPRC:$FRB))]>; + [(set F8RC:$FRT, (fadd F8RC:$FRA, F8RC:$FRB))]>; def FADDS : AForm_2<59, 21, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), + (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB), "fadds $FRT, $FRA, $FRB", []>; def FDIV : AForm_2<63, 18, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), + (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB), "fdiv $FRT, $FRA, $FRB", - [(set FPRC:$FRT, (fdiv FPRC:$FRA, FPRC:$FRB))]>; + [(set F8RC:$FRT, (fdiv F8RC:$FRA, F8RC:$FRB))]>; def FDIVS : AForm_2<59, 18, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), + (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB), "fdivs $FRT, $FRA, $FRB", []>; def FMUL : AForm_3<63, 25, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), + (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB), "fmul $FRT, $FRA, $FRB", - [(set FPRC:$FRT, (fmul FPRC:$FRA, FPRC:$FRB))]>; + [(set F8RC:$FRT, (fmul F8RC:$FRA, F8RC:$FRB))]>; def FMULS : AForm_3<59, 25, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), + (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB), "fmuls $FRT, $FRA, $FRB", []>; def FSUB : AForm_2<63, 20, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), + (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB), "fsub $FRT, $FRA, $FRB", - [(set FPRC:$FRT, (fsub FPRC:$FRA, FPRC:$FRB))]>; + [(set F8RC:$FRT, (fsub F8RC:$FRA, F8RC:$FRB))]>; def FSUBS : AForm_2<59, 20, - (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB), + (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB), "fsubs $FRT, $FRA, $FRB", []>; Index: llvm/lib/Target/PowerPC/PowerPCBranchSelector.cpp diff -u llvm/lib/Target/PowerPC/PowerPCBranchSelector.cpp:1.14 llvm/lib/Target/PowerPC/PowerPCBranchSelector.cpp:1.15 --- llvm/lib/Target/PowerPC/PowerPCBranchSelector.cpp:1.14 Fri Aug 26 18:41:27 2005 +++ llvm/lib/Target/PowerPC/PowerPCBranchSelector.cpp Fri Sep 30 20:34:18 2005 @@ -41,7 +41,8 @@ // keeping the offsets up to date later when we emit long branch glue. return 12; case PPC::IMPLICIT_DEF_GPR: // no asm emitted - case PPC::IMPLICIT_DEF_FP: // no asm emitted + case PPC::IMPLICIT_DEF_F4: // no asm emitted + case PPC::IMPLICIT_DEF_F8: // no asm emitted return 0; default: break; Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.td diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.td:1.7 llvm/lib/Target/PowerPC/PPC32RegisterInfo.td:1.8 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.td:1.7 Fri Aug 19 14:13:20 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.td Fri Sep 30 20:34:18 2005 @@ -39,8 +39,12 @@ }]; } -def FPRC : RegisterClass<"PPC32", f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7, +def F8RC : RegisterClass<"PPC32", f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>; +def F4RC : RegisterClass<"PPC32", f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7, + F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, + F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>; + def CRRC : RegisterClass<"PPC32", i32, 32, [CR0, CR1, CR5, CR6, CR7, CR2, CR3, CR4]>; Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.27 llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.28 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.27 Fri Sep 30 16:28:27 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Fri Sep 30 20:34:18 2005 @@ -43,47 +43,26 @@ ImmToIdxMap[PPC::ADDI] = PPC::ADD; } -static unsigned getIdx(const TargetRegisterClass *RC) { - if (RC == PPC32::GPRCRegisterClass) { - switch (RC->getSize()) { - default: assert(0 && "Invalid data size!"); - case 1: return 0; - case 2: return 1; - case 4: return 2; - } - } else if (RC == PPC32::FPRCRegisterClass) { - switch (RC->getSize()) { - default: assert(0 && "Invalid data size!"); - case 4: return 3; - case 8: return 4; - } - } else if (RC == PPC32::CRRCRegisterClass) { - switch (RC->getSize()) { - default: assert(0 && "Invalid data size!"); - case 4: return 2; - } - } - std::cerr << "Invalid register class to getIdx()!\n"; - abort(); -} - void PPC32RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, int FrameIdx, const TargetRegisterClass *RC) const { - static const unsigned Opcode[] = { - PPC::STB, PPC::STH, PPC::STW, PPC::STFS, PPC::STFD - }; - unsigned OC = Opcode[getIdx(RC)]; if (SrcReg == PPC::LR) { BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11); - addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx); + addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx); } else if (RC == PPC32::CRRCRegisterClass) { BuildMI(MBB, MI, PPC::MFCR, 0, PPC::R11); - addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx); + addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx); + } else if (RC == PPC32::GPRCRegisterClass) { + addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(SrcReg),FrameIdx); + } else if (RC == PPC32::F8RCRegisterClass) { + addFrameReference(BuildMI(MBB, MI, PPC::STFD, 3).addReg(SrcReg),FrameIdx); + } else if (RC == PPC32::F4RCRegisterClass) { + addFrameReference(BuildMI(MBB, MI, PPC::STFS, 3).addReg(SrcReg),FrameIdx); } else { - addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(SrcReg),FrameIdx); + assert(0 && "Unknown regclass!"); + abort(); } } @@ -92,18 +71,21 @@ MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC) const { - static const unsigned Opcode[] = { - PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LFS, PPC::LFD - }; - unsigned OC = Opcode[getIdx(RC)]; if (DestReg == PPC::LR) { - addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx); + addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx); BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11); } else if (RC == PPC32::CRRCRegisterClass) { - addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx); + addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx); BuildMI(MBB, MI, PPC::MTCRF, 1, DestReg).addReg(PPC::R11); + } else if (RC == PPC32::GPRCRegisterClass) { + addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, DestReg), FrameIdx); + } else if (RC == PPC32::F8RCRegisterClass) { + addFrameReference(BuildMI(MBB, MI, PPC::LFD, 2, DestReg), FrameIdx); + } else if (RC == PPC32::F4RCRegisterClass) { + addFrameReference(BuildMI(MBB, MI, PPC::LFS, 2, DestReg), FrameIdx); } else { - addFrameReference(BuildMI(MBB, MI, OC, 2, DestReg), FrameIdx); + assert(0 && "Unknown regclass!"); + abort(); } } @@ -115,8 +97,10 @@ if (RC == PPC32::GPRCRegisterClass) { BuildMI(MBB, MI, PPC::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg); - } else if (RC == PPC32::FPRCRegisterClass) { - BuildMI(MBB, MI, PPC::FMR, 1, DestReg).addReg(SrcReg); + } else if (RC == PPC32::F4RCRegisterClass) { + BuildMI(MBB, MI, PPC::FMRS, 1, DestReg).addReg(SrcReg); + } else if (RC == PPC32::F8RCRegisterClass) { + BuildMI(MBB, MI, PPC::FMRD, 1, DestReg).addReg(SrcReg); } else if (RC == PPC32::CRRCRegisterClass) { BuildMI(MBB, MI, PPC::MCRF, 1, DestReg).addReg(SrcReg); } else { @@ -130,6 +114,9 @@ switch (MI->getOpcode()) { default: break; case PPC::LWZ: + // + // case PPC::LFS: // ENABLE!! + // case PPC::LFD: if (MI->getOperand(1).isImmediate() && !MI->getOperand(1).getImmedValue() && MI->getOperand(2).isFrameIndex()) { @@ -161,8 +148,7 @@ return addFrameReference(BuildMI(PPC::LWZ, 2, OutReg), FrameIndex); } - } else if (Opc == PPC::FMR) { - // We currently always spill FP values as doubles. :( + } else if (Opc == PPC::FMRD) { if (OpNum == 0) { // move -> store unsigned InReg = MI->getOperand(1).getReg(); return addFrameReference(BuildMI(PPC::STFD, @@ -171,6 +157,15 @@ unsigned OutReg = MI->getOperand(0).getReg(); return addFrameReference(BuildMI(PPC::LFD, 2, OutReg), FrameIndex); } + } else if (Opc == PPC::FMRS) { + if (OpNum == 0) { // move -> store + unsigned InReg = MI->getOperand(1).getReg(); + return addFrameReference(BuildMI(PPC::STFS, + 3).addReg(InReg), FrameIndex); + } else { // move -> load + unsigned OutReg = MI->getOperand(0).getReg(); + return addFrameReference(BuildMI(PPC::LFS, 2, OutReg), FrameIndex); + } } return 0; } @@ -262,7 +257,8 @@ MI.SetMachineOperandReg(1, MI.getOperand(i).getReg()); MI.SetMachineOperandReg(2, PPC::R0); } else { - MI.SetMachineOperandConst(OffIdx,MachineOperand::MO_SignExtendedImmed,Offset); + MI.SetMachineOperandConst(OffIdx, MachineOperand::MO_SignExtendedImmed, + Offset); } } Index: llvm/lib/Target/PowerPC/PPC32InstrInfo.cpp diff -u llvm/lib/Target/PowerPC/PPC32InstrInfo.cpp:1.5 llvm/lib/Target/PowerPC/PPC32InstrInfo.cpp:1.6 --- llvm/lib/Target/PowerPC/PPC32InstrInfo.cpp:1.5 Fri Sep 9 13:17:41 2005 +++ llvm/lib/Target/PowerPC/PPC32InstrInfo.cpp Fri Sep 30 20:34:18 2005 @@ -57,7 +57,7 @@ destReg = MI.getOperand(0).getReg(); return true; } - } else if (oc == PPC::FMR) { // fmr r1, r2 + } else if (oc == PPC::FMRS || oc == PPC::FMRD) { // fmr r1, r2 assert(MI.getNumOperands() == 2 && MI.getOperand(0).isRegister() && MI.getOperand(1).isRegister() && From lattner at cs.uiuc.edu Fri Sep 30 20:35:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 20:35:23 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32CodeEmitter.cpp PPC32ISelDAGToDAG.cpp PPC32ISelLowering.cpp PPC32ISelPattern.cpp Message-ID: <200510010135.UAA01203@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32CodeEmitter.cpp updated: 1.34 -> 1.35 PPC32ISelDAGToDAG.cpp updated: 1.88 -> 1.89 PPC32ISelLowering.cpp updated: 1.27 -> 1.28 PPC32ISelPattern.cpp updated: 1.180 -> 1.181 --- Log message: Modify the ppc backend to use two register classes for FP: F8RC and F4RC. These are used to represent float and double values, and the two regclasses contain the same physical registers. --- Diffs of the changes: (+113 -44) PPC32CodeEmitter.cpp | 3 +- PPC32ISelDAGToDAG.cpp | 73 ++++++++++++++++++++++++++++++++++++++------------ PPC32ISelLowering.cpp | 13 ++++++-- PPC32ISelPattern.cpp | 68 +++++++++++++++++++++++++++++++--------------- 4 files changed, 113 insertions(+), 44 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32CodeEmitter.cpp diff -u llvm/lib/Target/PowerPC/PPC32CodeEmitter.cpp:1.34 llvm/lib/Target/PowerPC/PPC32CodeEmitter.cpp:1.35 --- llvm/lib/Target/PowerPC/PPC32CodeEmitter.cpp:1.34 Wed Aug 24 18:08:16 2005 +++ llvm/lib/Target/PowerPC/PPC32CodeEmitter.cpp Fri Sep 30 20:35:02 2005 @@ -125,7 +125,8 @@ emitWord(getBinaryCodeForInstr(*I)); break; case PPC::IMPLICIT_DEF_GPR: - case PPC::IMPLICIT_DEF_FP: + case PPC::IMPLICIT_DEF_F8: + case PPC::IMPLICIT_DEF_F4: break; // pseudo opcode, no side effects case PPC::MovePCtoLR: assert(0 && "CodeEmitter does not support MovePCtoLR instruction"); Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.88 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.89 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.88 Fri Sep 30 18:43:37 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Fri Sep 30 20:35:02 2005 @@ -443,8 +443,10 @@ LHS, getI32Imm(Lo16(Imm))); return CurDAG->getTargetNode(U ? PPC::CMPLW : PPC::CMPW, MVT::i32, LHS, Select(RHS)); + } else if (LHS.getValueType() == MVT::f32) { + return CurDAG->getTargetNode(PPC::FCMPUS, MVT::i32, LHS, Select(RHS)); } else { - return CurDAG->getTargetNode(PPC::FCMPU, MVT::i32, LHS, Select(RHS)); + return CurDAG->getTargetNode(PPC::FCMPUD, MVT::i32, LHS, Select(RHS)); } } @@ -679,8 +681,10 @@ case ISD::UNDEF: if (N->getValueType(0) == MVT::i32) CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_GPR, MVT::i32); - else - CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_FP, N->getValueType(0)); + else if (N->getValueType(0) == MVT::f32) + CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F4, MVT::f32); + else + CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F8, MVT::f64); return SDOperand(N, 0); case ISD::FrameIndex: { int FI = cast(N)->getIndex(); @@ -749,10 +753,16 @@ return SDOperand(Result.Val, Op.ResNo); } case PPCISD::FSEL: - CurDAG->SelectNodeTo(N, PPC::FSEL, N->getValueType(0), - Select(N->getOperand(0)), - Select(N->getOperand(1)), - Select(N->getOperand(2))); + if (N->getValueType(0) == MVT::f32) + CurDAG->SelectNodeTo(N, PPC::FSELS, MVT::f32, + Select(N->getOperand(0)), + Select(N->getOperand(1)), + Select(N->getOperand(2))); + else + CurDAG->SelectNodeTo(N, PPC::FSELD, MVT::f64, + Select(N->getOperand(0)), + Select(N->getOperand(1)), + Select(N->getOperand(2))); return SDOperand(N, 0); case PPCISD::FCFID: CurDAG->SelectNodeTo(N, PPC::FCFID, N->getValueType(0), @@ -956,15 +966,17 @@ return SDOperand(N, 0); } case ISD::FABS: - CurDAG->SelectNodeTo(N, PPC::FABS, N->getValueType(0), - Select(N->getOperand(0))); + if (N->getValueType(0) == MVT::f32) + CurDAG->SelectNodeTo(N, PPC::FABSS, MVT::f32, Select(N->getOperand(0))); + else + CurDAG->SelectNodeTo(N, PPC::FABSD, MVT::f64, Select(N->getOperand(0))); return SDOperand(N, 0); case ISD::FP_EXTEND: assert(MVT::f64 == N->getValueType(0) && MVT::f32 == N->getOperand(0).getValueType() && "Illegal FP_EXTEND"); // We need to emit an FMR to make sure that the result has the right value // type. - CurDAG->SelectNodeTo(N, PPC::FMR, MVT::f64, Select(N->getOperand(0))); + CurDAG->SelectNodeTo(N, PPC::FMRSD, MVT::f64, Select(N->getOperand(0))); return SDOperand(N, 0); case ISD::FP_ROUND: assert(MVT::f32 == N->getValueType(0) && @@ -978,7 +990,8 @@ unsigned Opc; switch (Val.isTargetOpcode() ? Val.getTargetOpcode() : 0) { default: Opc = 0; break; - case PPC::FABS: Opc = PPC::FNABS; break; + case PPC::FABSS: Opc = PPC::FNABSS; break; + case PPC::FABSD: Opc = PPC::FNABSD; break; case PPC::FMADD: Opc = PPC::FNMADD; break; case PPC::FMADDS: Opc = PPC::FNMADDS; break; case PPC::FMSUB: Opc = PPC::FNMSUB; break; @@ -988,7 +1001,7 @@ // inverted opcode and the original instruction's operands. Otherwise, // fall through and generate a fneg instruction. if (Opc) { - if (PPC::FNABS == Opc) + if (Opc == PPC::FNABSS || Opc == PPC::FNABSD) CurDAG->SelectNodeTo(N, Opc, Ty, Val.getOperand(0)); else CurDAG->SelectNodeTo(N, Opc, Ty, Val.getOperand(0), @@ -996,7 +1009,10 @@ return SDOperand(N, 0); } } - CurDAG->SelectNodeTo(N, PPC::FNEG, Ty, Val); + if (Ty == MVT::f32) + CurDAG->SelectNodeTo(N, PPC::FNEGS, MVT::f32, Val); + else + CurDAG->SelectNodeTo(N, PPC::FNEGS, MVT::f64, Val); return SDOperand(N, 0); } case ISD::FSQRT: { @@ -1090,9 +1106,26 @@ case MVT::f64: Opc = isIdx ? PPC::LFDX : PPC::LFD; break; } - CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other, - Op1, Op2, Select(N->getOperand(0))); - return SDOperand(N, Op.ResNo); + // If this is an f32 -> f64 load, emit the f32 load, then use an 'extending + // copy'. + if (TypeBeingLoaded != MVT::f32 || N->getOpcode() == ISD::LOAD) { + CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other, + Op1, Op2, Select(N->getOperand(0))); + return SDOperand(N, Op.ResNo); + } else { + std::vector Ops; + Ops.push_back(Op1); + Ops.push_back(Op2); + Ops.push_back(Select(N->getOperand(0))); + SDOperand Res = CurDAG->getTargetNode(Opc, MVT::f32, MVT::Other, Ops); + SDOperand Ext = CurDAG->getTargetNode(PPC::FMRSD, MVT::f64, Res); + CodeGenMap[Op.getValue(0)] = Ext; + CodeGenMap[Op.getValue(1)] = Res.getValue(1); + if (Op.ResNo) + return Res.getValue(1); + else + return Ext; + } } case ISD::TRUNCSTORE: @@ -1250,7 +1283,13 @@ unsigned BROpc = getBCCForSetCC(CC); bool isFP = MVT::isFloatingPoint(N->getValueType(0)); - unsigned SelectCCOp = isFP ? PPC::SELECT_CC_FP : PPC::SELECT_CC_Int; + unsigned SelectCCOp; + if (MVT::isInteger(N->getValueType(0))) + SelectCCOp = PPC::SELECT_CC_Int; + else if (N->getValueType(0) == MVT::f32) + SelectCCOp = PPC::SELECT_CC_F4; + else + SelectCCOp = PPC::SELECT_CC_F8; CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), CCReg, Select(N->getOperand(2)), Select(N->getOperand(3)), getI32Imm(BROpc)); Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.27 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.28 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.27 Wed Sep 28 17:29:58 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Fri Sep 30 20:35:02 2005 @@ -33,8 +33,8 @@ // Set up the register classes. addRegisterClass(MVT::i32, PPC32::GPRCRegisterClass); - addRegisterClass(MVT::f32, PPC32::FPRCRegisterClass); - addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass); + addRegisterClass(MVT::f32, PPC32::F4RCRegisterClass); + addRegisterClass(MVT::f64, PPC32::F8RCRegisterClass); // PowerPC has no intrinsics for these particular operations setOperationAction(ISD::MEMMOVE, MVT::Other, Expand); @@ -396,7 +396,11 @@ ObjSize = (ObjectVT == MVT::f64) ? 8 : 4; if (!ArgLive) break; if (FPR_remaining > 0) { - unsigned VReg = RegMap->createVirtualRegister(&PPC32::FPRCRegClass); + unsigned VReg; + if (ObjectVT == MVT::f32) + VReg = RegMap->createVirtualRegister(&PPC32::F4RCRegClass); + else + VReg = RegMap->createVirtualRegister(&PPC32::F8RCRegClass); MF.addLiveIn(FPR[FPR_idx], VReg); argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, ObjectVT); --FPR_remaining; @@ -724,7 +728,8 @@ PPC32TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, MachineBasicBlock *BB) { assert((MI->getOpcode() == PPC::SELECT_CC_Int || - MI->getOpcode() == PPC::SELECT_CC_FP) && + MI->getOpcode() == PPC::SELECT_CC_F4 || + MI->getOpcode() == PPC::SELECT_CC_F8) && "Unexpected instr type to insert"); // To "insert" a SELECT_CC instruction, we actually have to insert the diamond Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.180 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.181 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.180 Thu Sep 29 12:38:52 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Fri Sep 30 20:35:02 2005 @@ -87,9 +87,6 @@ inline unsigned MakeIntReg() { return RegMap->createVirtualRegister(PPC32::GPRCRegisterClass); } - inline unsigned MakeFPReg() { - return RegMap->createVirtualRegister(PPC32::FPRCRegisterClass); - } // dag -> dag expanders for integer divide by constant SDOperand BuildSDIVSequence(SDOperand N); @@ -593,8 +590,6 @@ unsigned ISel::SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC) { unsigned Result, Tmp1, Tmp2; bool AlreadySelected = false; - static const unsigned CompareOpcodes[] = - { PPC::FCMPU, PPC::FCMPU, PPC::CMPW, PPC::CMPLW }; // Allocate a condition register for this expression Result = RegMap->createVirtualRegister(PPC32::CRRCRegisterClass); @@ -626,8 +621,13 @@ else BuildMI(BB, PPC::CMPWI, 2, Result).addReg(Tmp1).addSImm(Tmp2); } else { - bool IsInteger = MVT::isInteger(LHS.getValueType()); - unsigned CompareOpc = CompareOpcodes[2 * IsInteger + U]; + unsigned CompareOpc; + if (MVT::isInteger(LHS.getValueType())) + CompareOpc = U ? PPC::CMPLW : PPC::CMPW; + else if (LHS.getValueType() == MVT::f32) + CompareOpc = PPC::FCMPUS; + else + CompareOpc = PPC::FCMPUD; Tmp1 = SelectExpr(LHS); Tmp2 = SelectExpr(RHS); BuildMI(BB, CompareOpc, 2, Result).addReg(Tmp1).addReg(Tmp2); @@ -815,7 +815,10 @@ Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); Tmp3 = SelectExpr(N.getOperand(2)); - BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + if (N.getOperand(0).getValueType() == MVT::f32) + BuildMI(BB, PPC::FSELS, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + else + BuildMI(BB, PPC::FSELD, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; case PPCISD::FCFID: Tmp1 = SelectExpr(N.getOperand(0)); @@ -832,8 +835,10 @@ case ISD::UNDEF: if (Node->getValueType(0) == MVT::i32) BuildMI(BB, PPC::IMPLICIT_DEF_GPR, 0, Result); + else if (Node->getValueType(0) == MVT::f32) + BuildMI(BB, PPC::IMPLICIT_DEF_F4, 0, Result); else - BuildMI(BB, PPC::IMPLICIT_DEF_FP, 0, Result); + BuildMI(BB, PPC::IMPLICIT_DEF_F8, 0, Result); return Result; case ISD::DYNAMIC_STACKALLOC: // Generate both result values. FIXME: Need a better commment here? @@ -1011,7 +1016,8 @@ case MVT::f64: case MVT::f32: assert(FPR_idx < 13 && "Too many fp args"); - BuildMI(BB, PPC::FMR, 1, FPR[FPR_idx]).addReg(ArgVR[i]); + BuildMI(BB, N.getOperand(i+2).getValueType() == MVT::f32 ? PPC::FMRS : + PPC::FMRD, 1, FPR[FPR_idx]).addReg(ArgVR[i]); CallMI->addRegOperand(FPR[FPR_idx], MachineOperand::Use); ++FPR_idx; break; @@ -1033,14 +1039,15 @@ } break; case MVT::f32: + BuildMI(BB, PPC::FMRS, 1, Result).addReg(PPC::F1); + break; case MVT::f64: - BuildMI(BB, PPC::FMR, 1, Result).addReg(PPC::F1); + BuildMI(BB, PPC::FMRD, 1, Result).addReg(PPC::F1); break; } return Result+N.ResNo; } - case ISD::SIGN_EXTEND: case ISD::SIGN_EXTEND_INREG: Tmp1 = SelectExpr(N.getOperand(0)); switch(cast(Node->getOperand(1))->getVT()) { @@ -1063,8 +1070,10 @@ Tmp1 = dyn_cast(Node->getOperand(1))->getReg(); if (MVT::isInteger(DestType)) BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp1).addReg(Tmp1); + else if (DestType == MVT::f32) + BuildMI(BB, PPC::FMRS, 1, Result).addReg(Tmp1); else - BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1); + BuildMI(BB, PPC::FMRD, 1, Result).addReg(Tmp1); return Result; case ISD::SHL: @@ -1655,16 +1664,26 @@ BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); } else if (ISD::FABS == N.getOperand(0).getOpcode()) { Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - BuildMI(BB, PPC::FNABS, 1, Result).addReg(Tmp1); + if (N.getOperand(0).getValueType() == MVT::f32) + BuildMI(BB, PPC::FNABSS, 1, Result).addReg(Tmp1); + else + BuildMI(BB, PPC::FNABSD, 1, Result).addReg(Tmp1); + } else { Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, PPC::FNEG, 1, Result).addReg(Tmp1); + if (N.getOperand(0).getValueType() == MVT::f32) + BuildMI(BB, PPC::FNEGS, 1, Result).addReg(Tmp1); + else + BuildMI(BB, PPC::FNEGD, 1, Result).addReg(Tmp1); } return Result; case ISD::FABS: Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, PPC::FABS, 1, Result).addReg(Tmp1); + if (N.getOperand(0).getValueType() == MVT::f32) + BuildMI(BB, PPC::FABSS, 1, Result).addReg(Tmp1); + else + BuildMI(BB, PPC::FABSD, 1, Result).addReg(Tmp1); return Result; case ISD::FSQRT: @@ -1686,7 +1705,7 @@ N.getOperand(0).getValueType() == MVT::f32 && "only f32 to f64 conversion supported here"); Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1); + BuildMI(BB, PPC::FMRSD, 1, Result).addReg(Tmp1); return Result; } return 0; @@ -1735,9 +1754,10 @@ Tmp2 = cast(N.getOperand(1))->getReg(); if (Tmp1 != Tmp2) { - if (N.getOperand(2).getValueType() == MVT::f64 || - N.getOperand(2).getValueType() == MVT::f32) - BuildMI(BB, PPC::FMR, 1, Tmp2).addReg(Tmp1); + if (N.getOperand(2).getValueType() == MVT::f64) + BuildMI(BB, PPC::FMRD, 1, Tmp2).addReg(Tmp1); + else if (N.getOperand(2).getValueType() == MVT::f32) + BuildMI(BB, PPC::FMRS, 1, Tmp2).addReg(Tmp1); else BuildMI(BB, PPC::OR, 2, Tmp2).addReg(Tmp1).addReg(Tmp1); } @@ -1747,8 +1767,10 @@ Tmp1 = cast(N.getOperand(1))->getReg(); if (N.getOperand(1).getValueType() == MVT::i32) BuildMI(BB, PPC::IMPLICIT_DEF_GPR, 0, Tmp1); + else if (N.getOperand(1).getValueType() == MVT::f32) + BuildMI(BB, PPC::IMPLICIT_DEF_F4, 0, Tmp1); else - BuildMI(BB, PPC::IMPLICIT_DEF_FP, 0, Tmp1); + BuildMI(BB, PPC::IMPLICIT_DEF_F8, 0, Tmp1); return; case ISD::RET: switch (N.getNumOperands()) { @@ -1771,8 +1793,10 @@ default: assert(0 && "Unknown return type!"); case MVT::f64: + BuildMI(BB, PPC::FMRD, 1, PPC::F1).addReg(Tmp1); + break; case MVT::f32: - BuildMI(BB, PPC::FMR, 1, PPC::F1).addReg(Tmp1); + BuildMI(BB, PPC::FMRS, 1, PPC::F1).addReg(Tmp1); break; case MVT::i32: BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1); From lattner at cs.uiuc.edu Fri Sep 30 21:51:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 30 Sep 2005 21:51:48 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200510010251.VAA03112@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.89 -> 1.90 --- Log message: fix typo --- Diffs of the changes: (+1 -1) PPC32ISelDAGToDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.89 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.90 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.89 Fri Sep 30 20:35:02 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Fri Sep 30 21:51:36 2005 @@ -1012,7 +1012,7 @@ if (Ty == MVT::f32) CurDAG->SelectNodeTo(N, PPC::FNEGS, MVT::f32, Val); else - CurDAG->SelectNodeTo(N, PPC::FNEGS, MVT::f64, Val); + CurDAG->SelectNodeTo(N, PPC::FNEGD, MVT::f64, Val); return SDOperand(N, 0); } case ISD::FSQRT: { From jeffc at jolt-lang.org Fri Sep 30 22:57:26 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Fri, 30 Sep 2005 22:57:26 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200510010357.WAA04088@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.85 -> 1.86 --- Log message: Fix VC++ warnings. --- Diffs of the changes: (+4 -4) SelectionDAGISel.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.85 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.86 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.85 Wed Sep 28 17:28:18 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Sep 30 22:57:14 2005 @@ -148,7 +148,7 @@ AI != E; ++AI) InitializeRegForValue(AI); - Function::iterator BB = Fn.begin(), E = Fn.end(); + Function::iterator BB = Fn.begin(), EB = Fn.end(); for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) if (AllocaInst *AI = dyn_cast(I)) if (ConstantUInt *CUI = dyn_cast(AI->getArraySize())) { @@ -170,8 +170,8 @@ MF.getFrameInfo()->CreateStackObject((unsigned)TySize, Align); } - for (; BB != E; ++BB) - for (BasicBlock::iterator I = BB->begin(), e = BB->end(); I != e; ++I) + for (; BB != EB; ++BB) + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) if (!I->use_empty() && isUsedOutsideOfDefiningBlock(I)) if (!isa(I) || !StaticAllocaMap.count(cast(I))) @@ -180,7 +180,7 @@ // Create an initial MachineBasicBlock for each LLVM BasicBlock in F. This // also creates the initial PHI MachineInstrs, though none of the input // operands are populated. - for (Function::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { + for (BB = Fn.begin(), EB = Fn.end(); BB != EB; ++BB) { MachineBasicBlock *MBB = new MachineBasicBlock(BB); MBBMap[BB] = MBB; MF.getBasicBlockList().push_back(MBB); From jeffc at jolt-lang.org Fri Sep 30 22:57:26 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Fri, 30 Sep 2005 22:57:26 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LowerInvoke.cpp Message-ID: <200510010357.WAA04092@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LowerInvoke.cpp updated: 1.32 -> 1.33 --- Log message: Fix VC++ warnings. --- Diffs of the changes: (+0 -1) LowerInvoke.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/Transforms/Scalar/LowerInvoke.cpp diff -u llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.32 llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.33 --- llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.32 Thu Sep 29 12:44:20 2005 +++ llvm/lib/Transforms/Scalar/LowerInvoke.cpp Fri Sep 30 22:57:14 2005 @@ -365,7 +365,6 @@ Instruction *U = Users.back(); Users.pop_back(); - BasicBlock *UseBlock; if (!isa(U)) { MarkBlocksLiveIn(U->getParent(), LiveBBs); } else { From lattner at cs.uiuc.edu Sat Oct 1 02:45:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 1 Oct 2005 02:45:21 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200510010745.CAA04763@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.28 -> 1.29 --- Log message: Add some very paranoid checking for operand/result reg class matchup For instructions that define multiple results, use the right regclass to define the result, not always the rc of result #0 --- Diffs of the changes: (+20 -3) ScheduleDAG.cpp | 23 ++++++++++++++++++++--- 1 files changed, 20 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.28 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.29 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.28 Fri Sep 30 19:08:23 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Sat Oct 1 02:45:09 2005 @@ -909,7 +909,7 @@ MI->addRegOperand(ResultReg, MachineOperand::Def); for (unsigned i = 1; i != NumResults; ++i) { assert(OpInfo[i].RegClass && "Isn't a register operand!"); - MI->addRegOperand(RegMap->createVirtualRegister(OpInfo[0].RegClass), + MI->addRegOperand(RegMap->createVirtualRegister(OpInfo[i].RegClass), MachineOperand::Def); } return ResultReg; @@ -951,8 +951,17 @@ assert(Node->getOperand(i).getValueType() != MVT::Other && Node->getOperand(i).getValueType() != MVT::Flag && "Chain and flag operands should occur at end of operand list!"); + + // Get/emit the operand. + unsigned VReg = getVR(Node->getOperand(i)); + MI->addRegOperand(VReg, MachineOperand::Use); - MI->addRegOperand(getVR(Node->getOperand(i)), MachineOperand::Use); + // Verify that it is right. + assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); + assert(II.OpInfo[i+NumResults].RegClass && + "Don't have operand info for this instruction!"); + assert(RegMap->getRegClass(VReg) == II.OpInfo[i+NumResults].RegClass && + "Register class of operand and regclass of use don't agree!"); } else if (ConstantSDNode *C = dyn_cast(Node->getOperand(i))) { MI->addZeroExtImm64Operand(C->getValue()); @@ -979,7 +988,15 @@ assert(Node->getOperand(i).getValueType() != MVT::Other && Node->getOperand(i).getValueType() != MVT::Flag && "Chain and flag operands should occur at end of operand list!"); - MI->addRegOperand(getVR(Node->getOperand(i)), MachineOperand::Use); + unsigned VReg = getVR(Node->getOperand(i)); + MI->addRegOperand(VReg, MachineOperand::Use); + + // Verify that it is right. + assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); + assert(II.OpInfo[i+NumResults].RegClass && + "Don't have operand info for this instruction!"); + assert(RegMap->getRegClass(VReg) == II.OpInfo[i+NumResults].RegClass && + "Register class of operand and regclass of use don't agree!"); } } From lattner at cs.uiuc.edu Sat Oct 1 18:02:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 1 Oct 2005 18:02:53 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Message-ID: <200510012302.SAA11034@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32RegisterInfo.cpp updated: 1.28 -> 1.29 --- Log message: like the comment says, enable this --- Diffs of the changes: (+1 -3) PPC32RegisterInfo.cpp | 4 +--- 1 files changed, 1 insertion(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.28 llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.29 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.28 Fri Sep 30 20:34:18 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Sat Oct 1 18:02:40 2005 @@ -114,9 +114,7 @@ switch (MI->getOpcode()) { default: break; case PPC::LWZ: - // - // case PPC::LFS: // ENABLE!! - // + case PPC::LFS: case PPC::LFD: if (MI->getOperand(1).isImmediate() && !MI->getOperand(1).getImmedValue() && MI->getOperand(2).isFrameIndex()) { From lattner at cs.uiuc.edu Sat Oct 1 18:06:38 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 1 Oct 2005 18:06:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200510012306.SAA11070@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.90 -> 1.91 --- Log message: Minor tweak to the branch selector. When emitting a two-way branch, and if we're in a single-mbb loop, make sure to emit the backwards branch as the conditional branch instead of the uncond branch. For example, emit this: LBBl29_z__44: stw r9, 0(r15) stw r9, 4(r15) stw r9, 8(r15) stw r9, 12(r15) addi r15, r15, 16 addi r8, r8, 1 cmpw cr0, r8, r28 ble cr0, LBBl29_z__44 b LBBl29_z__48 *** NOT PART OF LOOP Instead of: LBBl29_z__44: stw r9, 0(r15) stw r9, 4(r15) stw r9, 8(r15) stw r9, 12(r15) addi r15, r15, 16 addi r8, r8, 1 cmpw cr0, r8, r28 bgt cr0, LBBl29_z__48 *** PART OF LOOP! b LBBl29_z__44 The former sequence has one fewer dispatch group for the loop body. --- Diffs of the changes: (+17 -6) PPC32ISelDAGToDAG.cpp | 23 +++++++++++++++++------ 1 files changed, 17 insertions(+), 6 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.90 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.91 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.90 Fri Sep 30 21:51:36 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Sat Oct 1 18:06:26 2005 @@ -1445,20 +1445,31 @@ cast(N->getOperand(4))->getBasicBlock(); ISD::CondCode CC = cast(N->getOperand(1))->get(); SDOperand CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC); - unsigned Opc = getBCCForSetCC(CC); // If this is a two way branch, then grab the fallthrough basic block // argument and build a PowerPC branch pseudo-op, suitable for long branch // conversion if necessary by the branch selection pass. Otherwise, emit a // standard conditional branch. if (N->getOpcode() == ISD::BRTWOWAY_CC) { - MachineBasicBlock *Fallthrough = - cast(N->getOperand(5))->getBasicBlock(); + SDOperand CondTrueBlock = N->getOperand(4); + SDOperand CondFalseBlock = N->getOperand(5); + + // If the false case is the current basic block, then this is a self loop. + // We do not want to emit "Loop: ... brcond Out; br Loop", as it adds an + // extra dispatch group to the loop. Instead, invert the condition and + // emit "Loop: ... br!cond Loop; br Out + if (cast(CondFalseBlock)->getBasicBlock() == BB) { + std::swap(CondTrueBlock, CondFalseBlock); + CC = getSetCCInverse(CC, + MVT::isInteger(N->getOperand(2).getValueType())); + } + + unsigned Opc = getBCCForSetCC(CC); SDOperand CB = CurDAG->getTargetNode(PPC::COND_BRANCH, MVT::Other, CondCode, getI32Imm(Opc), - N->getOperand(4), N->getOperand(5), + CondTrueBlock, CondFalseBlock, Chain); - CurDAG->SelectNodeTo(N, PPC::B, MVT::Other, N->getOperand(5), CB); + CurDAG->SelectNodeTo(N, PPC::B, MVT::Other, CondFalseBlock, CB); } else { // Iterate to the next basic block ilist::iterator It = BB; @@ -1470,7 +1481,7 @@ // the PowerPC Branch Selection pass to crash. if (It == BB->getParent()->end()) It = Dest; CurDAG->SelectNodeTo(N, PPC::COND_BRANCH, MVT::Other, CondCode, - getI32Imm(Opc), N->getOperand(4), + getI32Imm(getBCCForSetCC(CC)), N->getOperand(4), CurDAG->getBasicBlock(It), Chain); } return SDOperand(N, 0); From lattner at cs.uiuc.edu Sun Oct 2 01:23:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 01:23:32 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200510020623.BAA12153@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.62 -> 1.63 --- Log message: Expose the actual valuetype of each register class --- Diffs of the changes: (+8 -2) MRegisterInfo.h | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.62 llvm/include/llvm/Target/MRegisterInfo.h:1.63 --- llvm/include/llvm/Target/MRegisterInfo.h:1.62 Fri Sep 30 12:47:48 2005 +++ llvm/include/llvm/Target/MRegisterInfo.h Sun Oct 2 01:23:19 2005 @@ -17,6 +17,7 @@ #define LLVM_TARGET_MREGISTERINFO_H #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/Codegen/ValueTypes.h" #include #include @@ -44,13 +45,18 @@ typedef const unsigned* const_iterator; private: + MVT::ValueType VT; const unsigned RegSize, Alignment; // Size & Alignment of register in bytes const iterator RegsBegin, RegsEnd; public: - TargetRegisterClass(unsigned RS, unsigned Al, iterator RB, iterator RE) - : RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {} + TargetRegisterClass(MVT::ValueType vt, unsigned RS, unsigned Al, iterator RB, iterator RE) + : VT(vt), RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {} virtual ~TargetRegisterClass() {} // Allow subclasses + /// getType - Return the declared value type for this register class. + /// + MVT::ValueType getType() const { return VT; } + // begin/end - Return all of the registers in this class. iterator begin() const { return RegsBegin; } iterator end() const { return RegsEnd; } From lattner at cs.uiuc.edu Sun Oct 2 01:23:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 01:23:49 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200510020623.BAA12188@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.35 -> 1.36 --- Log message: Emit the value type for each register class. --- Diffs of the changes: (+4 -3) RegisterInfoEmitter.cpp | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.35 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.36 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.35 Fri Sep 30 12:48:44 2005 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Sun Oct 2 01:23:37 2005 @@ -141,9 +141,10 @@ const CodeGenRegisterClass &RC = RegisterClasses[i]; OS << RC.MethodBodies << "\n"; OS << RC.getName() << "Class::" << RC.getName() - << "Class() : TargetRegisterClass(" << RC.SpillSize/8 << ", " - << RC.SpillAlignment/8 << ", " << RC.getName() << ", " - << RC.getName() << " + " << RC.Elements.size() << ") {}\n"; + << "Class() : TargetRegisterClass(MVT::" << getEnumName(RC.VT) << "," + << RC.SpillSize/8 << ", " + << RC.SpillAlignment/8 << ", " << RC.getName() << ", " + << RC.getName() << " + " << RC.Elements.size() << ") {}\n"; } OS << "}\n"; From lattner at cs.uiuc.edu Sun Oct 2 01:24:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 01:24:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp Message-ID: <200510020624.BAA12198@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9RegisterInfo.cpp updated: 1.8 -> 1.9 --- Log message: Adjust to change in ctor --- Diffs of the changes: (+5 -5) SparcV9RegisterInfo.cpp | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp diff -u llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp:1.8 llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp:1.9 --- llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp:1.8 Fri Sep 30 12:49:27 2005 +++ llvm/lib/Target/SparcV9/SparcV9RegisterInfo.cpp Sun Oct 2 01:23:51 2005 @@ -43,7 +43,7 @@ SparcV9::g7, SparcV9::o6 }; struct IRClass : public TargetRegisterClass { - IRClass() : TargetRegisterClass(8, 8, IR, IR + 32) {} + IRClass() : TargetRegisterClass(MVT::i64, 8, 8, IR, IR + 32) {} } IRInstance; @@ -71,7 +71,7 @@ // one (32, 34, ...), and they must contain double-fp or quad-fp // values... see below about the aliasing problems. struct FRClass : public TargetRegisterClass { - FRClass() : TargetRegisterClass(4, 8, FR, FR + 64) {} + FRClass() : TargetRegisterClass(MVT::f32, 4, 8, FR, FR + 64) {} } FRInstance; @@ -80,7 +80,7 @@ SparcV9::xcc, SparcV9::icc, SparcV9::ccr }; struct ICCRClass : public TargetRegisterClass { - ICCRClass() : TargetRegisterClass(1, 8, ICCR, ICCR + 3) {} + ICCRClass() : TargetRegisterClass(MVT::i1, 1, 8, ICCR, ICCR + 3) {} } ICCRInstance; @@ -89,7 +89,7 @@ SparcV9::fcc0, SparcV9::fcc1, SparcV9::fcc2, SparcV9::fcc3 }; struct FCCRClass : public TargetRegisterClass { - FCCRClass() : TargetRegisterClass(1, 8, FCCR, FCCR + 4) {} + FCCRClass() : TargetRegisterClass(MVT::i1, 1, 8, FCCR, FCCR + 4) {} } FCCRInstance; @@ -98,7 +98,7 @@ SparcV9::fsr }; struct SRClass : public TargetRegisterClass { - SRClass() : TargetRegisterClass(8, 8, SR, SR + 1) {} + SRClass() : TargetRegisterClass(MVT::i64, 8, 8, SR, SR + 1) {} } SRInstance; From lattner at cs.uiuc.edu Sun Oct 2 01:34:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 01:34:28 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200510020634.BAA12317@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.29 -> 1.30 --- Log message: Codegen CopyFromReg using the regclass that matches the valuetype of the destination vreg. --- Diffs of the changes: (+11 -9) ScheduleDAG.cpp | 20 +++++++++++--------- 1 files changed, 11 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.29 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.30 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.29 Sat Oct 1 02:45:09 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Sun Oct 2 01:34:16 2005 @@ -1031,11 +1031,11 @@ if (MRegisterInfo::isVirtualRegister(SrcReg)) { TRC = RegMap->getRegClass(SrcReg); } else { - // FIXME: we don't know what register class to generate this for. Do - // a brute force search and pick the first match. :( + // Pick the register class of the right type that contains this physreg. for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(), - E = MRI.regclass_end(); I != E; ++I) - if ((*I)->contains(SrcReg)) { + E = MRI.regclass_end(); I != E; ++I) + if ((*I)->getType() == Node->getValueType(0) && + (*I)->contains(SrcReg)) { TRC = *I; break; } @@ -1100,7 +1100,8 @@ Op.getOperand(i).getValueType() != MVT::Flag && "Chain and flag operands should occur at end of operand list!"); - MI->addRegOperand(EmitDAG(Op.getOperand(i)), MachineOperand::Use); + unsigned VReg = EmitDAG(Op.getOperand(i)); + MI->addRegOperand(VReg, MachineOperand::Use); } else if (ConstantSDNode *C = dyn_cast(Op.getOperand(i))) { MI->addZeroExtImm64Operand(C->getValue()); @@ -1126,7 +1127,8 @@ assert(Op.getOperand(i).getValueType() != MVT::Other && Op.getOperand(i).getValueType() != MVT::Flag && "Chain and flag operands should occur at end of operand list!"); - MI->addRegOperand(EmitDAG(Op.getOperand(i)), MachineOperand::Use); + unsigned VReg = EmitDAG(Op.getOperand(i)); + MI->addRegOperand(VReg, MachineOperand::Use); } } @@ -1188,11 +1190,11 @@ if (MRegisterInfo::isVirtualRegister(SrcReg)) { TRC = RegMap->getRegClass(SrcReg); } else { - // FIXME: we don't know what register class to generate this for. Do - // a brute force search and pick the first match. :( + // Pick the register class of the right type that contains this physreg. for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(), E = MRI.regclass_end(); I != E; ++I) - if ((*I)->contains(SrcReg)) { + if ((*I)->getType() == Op.Val->getValueType(0) && + (*I)->contains(SrcReg)) { TRC = *I; break; } From lattner at cs.uiuc.edu Sun Oct 2 01:37:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 01:37:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Message-ID: <200510020637.BAA12377@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelLowering.cpp updated: 1.28 -> 1.29 --- Log message: fix an f32/f64 type mismatch --- Diffs of the changes: (+6 -2) PPC32ISelLowering.cpp | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.28 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.29 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.28 Fri Sep 30 20:35:02 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Sun Oct 2 01:37:13 2005 @@ -130,13 +130,17 @@ default: assert(0 && "Wasn't expecting to be able to lower this!"); case ISD::FP_TO_SINT: { assert(MVT::isFloatingPoint(Op.getOperand(0).getValueType())); + SDOperand Src = Op.getOperand(0); + if (Src.getValueType() == MVT::f32) + Src = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Src); + switch (Op.getValueType()) { default: assert(0 && "Unhandled FP_TO_SINT type in custom expander!"); case MVT::i32: - Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Op.getOperand(0)); + Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Src); break; case MVT::i64: - Op = DAG.getNode(PPCISD::FCTIDZ, MVT::f64, Op.getOperand(0)); + Op = DAG.getNode(PPCISD::FCTIDZ, MVT::f64, Src); break; } From lattner at cs.uiuc.edu Sun Oct 2 01:58:35 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 01:58:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp PPC32ISelPattern.cpp PowerPCInstrInfo.td Message-ID: <200510020658.BAA12469@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.91 -> 1.92 PPC32ISelPattern.cpp updated: 1.181 -> 1.182 PowerPCInstrInfo.td updated: 1.115 -> 1.116 --- Log message: fsel can take a different FP type for the comparison and for the result. As such split the FSEL family into 4 things instead of just two. --- Diffs of the changes: (+37 -22) PPC32ISelDAGToDAG.cpp | 25 ++++++++++++++----------- PPC32ISelPattern.cpp | 7 +++++-- PowerPCInstrInfo.td | 27 ++++++++++++++++++--------- 3 files changed, 37 insertions(+), 22 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.91 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.92 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.91 Sat Oct 1 18:06:26 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Sun Oct 2 01:58:23 2005 @@ -752,18 +752,21 @@ CodeGenMap[Op.getValue(1)] = Result.getValue(1); return SDOperand(Result.Val, Op.ResNo); } - case PPCISD::FSEL: - if (N->getValueType(0) == MVT::f32) - CurDAG->SelectNodeTo(N, PPC::FSELS, MVT::f32, - Select(N->getOperand(0)), - Select(N->getOperand(1)), - Select(N->getOperand(2))); - else - CurDAG->SelectNodeTo(N, PPC::FSELD, MVT::f64, - Select(N->getOperand(0)), - Select(N->getOperand(1)), - Select(N->getOperand(2))); + case PPCISD::FSEL: { + unsigned Opc; + if (N->getValueType(0) == MVT::f32) { + Opc = N->getOperand(0).getValueType() == MVT::f32 ? + PPC::FSELSS : PPC::FSELSD; + } else { + Opc = N->getOperand(0).getValueType() == MVT::f64 ? + PPC::FSELDD : PPC::FSELDS; + } + CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), + Select(N->getOperand(0)), + Select(N->getOperand(1)), + Select(N->getOperand(2))); return SDOperand(N, 0); + } case PPCISD::FCFID: CurDAG->SelectNodeTo(N, PPC::FCFID, N->getValueType(0), Select(N->getOperand(0))); Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.181 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.182 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.181 Fri Sep 30 20:35:02 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sun Oct 2 01:58:23 2005 @@ -816,9 +816,12 @@ Tmp2 = SelectExpr(N.getOperand(1)); Tmp3 = SelectExpr(N.getOperand(2)); if (N.getOperand(0).getValueType() == MVT::f32) - BuildMI(BB, PPC::FSELS, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + Opc = N.getOperand(0).getValueType() == MVT::f32 ? + PPC::FSELSS : PPC::FSELSD; else - BuildMI(BB, PPC::FSELD, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + Opc = N.getOperand(0).getValueType() == MVT::f64 ? + PPC::FSELDD : PPC::FSELDS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; case PPCISD::FCFID: Tmp1 = SelectExpr(N.getOperand(0)); Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.115 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.116 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.115 Fri Sep 30 20:34:18 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Sun Oct 2 01:58:23 2005 @@ -791,15 +791,24 @@ (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), "fnmsubs $FRT, $FRA, $FRC, $FRB", []>; -// FSEL is artificially split into 4 and 8-byte forms. -def FSELD : AForm_1<63, 23, - (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), - "fsel $FRT, $FRA, $FRC, $FRB", - []>; -def FSELS : AForm_1<63, 23, - (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), - "fsel $FRT, $FRA, $FRC, $FRB", - []>; +// FSEL is artificially split into 4 and 8-byte forms for the comparison type +// and 4/8 byte forms for the result and operand type.. +def FSELDD : AForm_1<63, 23, + (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), + "fsel $FRT, $FRA, $FRC, $FRB", + []>; +def FSELSS : AForm_1<63, 23, + (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), + "fsel $FRT, $FRA, $FRC, $FRB", + []>; +def FSELDS : AForm_1<63, 23, // result Double, comparison Single + (ops F8RC:$FRT, F4RC:$FRA, F8RC:$FRC, F8RC:$FRB), + "fsel $FRT, $FRA, $FRC, $FRB", + []>; +def FSELSD : AForm_1<63, 23, // result Single, comparison Double + (ops F4RC:$FRT, F8RC:$FRA, F4RC:$FRC, F4RC:$FRB), + "fsel $FRT, $FRA, $FRC, $FRB", + []>; def FADD : AForm_2<63, 21, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB), "fadd $FRT, $FRA, $FRB", From lattner at cs.uiuc.edu Sun Oct 2 02:08:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 02:08:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp PPC32ISelPattern.cpp PowerPCInstrInfo.td Message-ID: <200510020708.CAA12580@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.92 -> 1.93 PPC32ISelPattern.cpp updated: 1.182 -> 1.183 PowerPCInstrInfo.td updated: 1.116 -> 1.117 --- Log message: another solution to the fsel issue. Instead of having 4 variants, just force the comparison to be 64-bits. This is fine because extensions from float to double are free. --- Diffs of the changes: (+25 -32) PPC32ISelDAGToDAG.cpp | 20 ++++++++------------ PPC32ISelPattern.cpp | 15 +++++++++------ PowerPCInstrInfo.td | 22 ++++++++-------------- 3 files changed, 25 insertions(+), 32 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.92 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.93 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.92 Sun Oct 2 01:58:23 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Sun Oct 2 02:07:49 2005 @@ -753,18 +753,14 @@ return SDOperand(Result.Val, Op.ResNo); } case PPCISD::FSEL: { - unsigned Opc; - if (N->getValueType(0) == MVT::f32) { - Opc = N->getOperand(0).getValueType() == MVT::f32 ? - PPC::FSELSS : PPC::FSELSD; - } else { - Opc = N->getOperand(0).getValueType() == MVT::f64 ? - PPC::FSELDD : PPC::FSELDS; - } - CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), - Select(N->getOperand(0)), - Select(N->getOperand(1)), - Select(N->getOperand(2))); + SDOperand Comparison = Select(N->getOperand(0)); + // Extend the comparison to 64-bits. + if (Comparison.getValueType() == MVT::f32) + Comparison = CurDAG->getTargetNode(PPC::FMRSD, MVT::f64, Comparison); + + unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FSELS : PPC::FSELD; + CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Comparison, + Select(N->getOperand(1)), Select(N->getOperand(2))); return SDOperand(N, 0); } case PPCISD::FCFID: Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.182 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.183 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.182 Sun Oct 2 01:58:23 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sun Oct 2 02:07:49 2005 @@ -815,12 +815,15 @@ Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); Tmp3 = SelectExpr(N.getOperand(2)); - if (N.getOperand(0).getValueType() == MVT::f32) - Opc = N.getOperand(0).getValueType() == MVT::f32 ? - PPC::FSELSS : PPC::FSELSD; - else - Opc = N.getOperand(0).getValueType() == MVT::f64 ? - PPC::FSELDD : PPC::FSELDS; + + // Extend the comparison to 64-bits if needed. + if (N.getOperand(0).getValueType() == MVT::f32) { + unsigned Tmp1New = MakeReg(MVT::f64); + BuildMI(BB, PPC::FMRSD, 1, Tmp1New).addReg(Tmp1); + Tmp1 = Tmp1New; + } + + Opc = N.Val->getValueType(0) == MVT::f32 ? PPC::FSELS : PPC::FSELD; BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; case PPCISD::FCFID: Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.116 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.117 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.116 Sun Oct 2 01:58:23 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Sun Oct 2 02:07:49 2005 @@ -791,21 +791,15 @@ (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), "fnmsubs $FRT, $FRA, $FRC, $FRB", []>; -// FSEL is artificially split into 4 and 8-byte forms for the comparison type +// FSEL is artificially split into 4 and 8-byte forms for the result. To avoid +// having 4 of these, force the comparison to always be an 8-byte double (code +// should use an FMRSD if the input comparison value really wants to be a float) // and 4/8 byte forms for the result and operand type.. -def FSELDD : AForm_1<63, 23, - (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), - "fsel $FRT, $FRA, $FRC, $FRB", - []>; -def FSELSS : AForm_1<63, 23, - (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), - "fsel $FRT, $FRA, $FRC, $FRB", - []>; -def FSELDS : AForm_1<63, 23, // result Double, comparison Single - (ops F8RC:$FRT, F4RC:$FRA, F8RC:$FRC, F8RC:$FRB), - "fsel $FRT, $FRA, $FRC, $FRB", - []>; -def FSELSD : AForm_1<63, 23, // result Single, comparison Double +def FSELD : AForm_1<63, 23, + (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), + "fsel $FRT, $FRA, $FRC, $FRB", + []>; +def FSELS : AForm_1<63, 23, (ops F4RC:$FRT, F8RC:$FRA, F4RC:$FRC, F4RC:$FRB), "fsel $FRT, $FRA, $FRC, $FRB", []>; From lattner at cs.uiuc.edu Sun Oct 2 02:11:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 02:11:08 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200510020711.CAA12646@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.30 -> 1.31 --- Log message: Add assertions to the trivial scheduler to check that the value types match up between defs and uses. --- Diffs of the changes: (+21 -0) ScheduleDAG.cpp | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.30 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.31 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.30 Sun Oct 2 01:34:16 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Sun Oct 2 02:10:55 2005 @@ -1102,6 +1102,20 @@ unsigned VReg = EmitDAG(Op.getOperand(i)); MI->addRegOperand(VReg, MachineOperand::Use); + + // Verify that it is right. + assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); + assert(II.OpInfo[i+NumResults].RegClass && + "Don't have operand info for this instruction!"); +#ifndef NDEBUG + if (RegMap->getRegClass(VReg) != II.OpInfo[i+NumResults].RegClass) { + std::cerr << "OP: "; + Op.getOperand(i).Val->dump(&DAG); std::cerr << "\nUSE: "; + Op.Val->dump(&DAG); std::cerr << "\n"; + } +#endif + assert(RegMap->getRegClass(VReg) == II.OpInfo[i+NumResults].RegClass && + "Register class of operand and regclass of use don't agree!"); } else if (ConstantSDNode *C = dyn_cast(Op.getOperand(i))) { MI->addZeroExtImm64Operand(C->getValue()); @@ -1129,6 +1143,13 @@ "Chain and flag operands should occur at end of operand list!"); unsigned VReg = EmitDAG(Op.getOperand(i)); MI->addRegOperand(VReg, MachineOperand::Use); + + // Verify that it is right. + assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); + assert(II.OpInfo[i+NumResults].RegClass && + "Don't have operand info for this instruction!"); + assert(RegMap->getRegClass(VReg) == II.OpInfo[i+NumResults].RegClass && + "Register class of operand and regclass of use don't agree!"); } } From lattner at cs.uiuc.edu Sun Oct 2 02:14:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 02:14:04 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaSubtarget.cpp Message-ID: <200510020714.CAA12709@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaSubtarget.cpp updated: 1.2 -> 1.3 --- Log message: Sort the cpu and features table, so that the alpha backend doesn't fail EVERY compile with an assertion that the tables are not sorted! --- Diffs of the changes: (+2 -2) AlphaSubtarget.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/Alpha/AlphaSubtarget.cpp diff -u llvm/lib/Target/Alpha/AlphaSubtarget.cpp:1.2 llvm/lib/Target/Alpha/AlphaSubtarget.cpp:1.3 --- llvm/lib/Target/Alpha/AlphaSubtarget.cpp:1.2 Fri Sep 30 15:24:38 2005 +++ llvm/lib/Target/Alpha/AlphaSubtarget.cpp Sun Oct 2 02:13:52 2005 @@ -30,8 +30,8 @@ { "ev56" , "Select the Alpha EV56 processor", 0 }, { "ev6" , "Select the Alpha EV6 processor", AlphaFeatureFIX }, { "ev67" , "Select the Alpha EV67 processor", AlphaFeatureFIX | AlphaFeatureCIX }, + { "generic", "Select instructions for a generic Alpha processor (EV56)", 0 }, { "pca56" , "Select the Alpha PCA56 processor", 0 }, - { "generic", "Select instructions for a generic Alpha processor (EV56)", 0 } }; /// Length of AlphaSubTypeKV. @@ -40,8 +40,8 @@ /// Sorted (by key) array of values for CPU features. static SubtargetFeatureKV AlphaFeatureKV[] = { + { "CIX", "Should CIX extentions be used" , AlphaFeatureCIX }, { "FIX" , "Should FIX extentions be used" , AlphaFeatureFIX }, - { "CIX", "Should CIX extentions be used" , AlphaFeatureCIX } }; /// Length of AlphaFeatureKV. static const unsigned AlphaFeatureKVSize = sizeof(AlphaFeatureKV) From lattner at cs.uiuc.edu Sun Oct 2 02:46:40 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 02:46:40 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200510020746.CAA12835@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.117 -> 1.118 --- Log message: add patterns for float binops and fma ops --- Diffs of the changes: (+12 -8) PowerPCInstrInfo.td | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.117 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.118 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.117 Sun Oct 2 02:07:49 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Sun Oct 2 02:46:28 2005 @@ -763,7 +763,8 @@ def FMADDS : AForm_1<59, 29, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), "fmadds $FRT, $FRA, $FRC, $FRB", - []>; + [(set F4RC:$FRT, (fadd (fmul F4RC:$FRA, F4RC:$FRC), + F4RC:$FRB))]>; def FMSUB : AForm_1<63, 28, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), "fmsub $FRT, $FRA, $FRC, $FRB", @@ -772,7 +773,8 @@ def FMSUBS : AForm_1<59, 28, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), "fmsubs $FRT, $FRA, $FRC, $FRB", - []>; + [(set F4RC:$FRT, (fsub (fmul F4RC:$FRA, F4RC:$FRC), + F4RC:$FRB))]>; def FNMADD : AForm_1<63, 31, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), "fnmadd $FRT, $FRA, $FRC, $FRB", @@ -781,7 +783,8 @@ def FNMADDS : AForm_1<59, 31, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), "fnmadds $FRT, $FRA, $FRC, $FRB", - []>; + [(set F4RC:$FRT, (fneg (fadd (fmul F4RC:$FRA, F4RC:$FRC), + F4RC:$FRB)))]>; def FNMSUB : AForm_1<63, 30, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), "fnmsub $FRT, $FRA, $FRC, $FRB", @@ -790,7 +793,8 @@ def FNMSUBS : AForm_1<59, 30, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), "fnmsubs $FRT, $FRA, $FRC, $FRB", - []>; + [(set F4RC:$FRT, (fneg (fsub (fmul F4RC:$FRA, F4RC:$FRC), + F4RC:$FRB)))]>; // FSEL is artificially split into 4 and 8-byte forms for the result. To avoid // having 4 of these, force the comparison to always be an 8-byte double (code // should use an FMRSD if the input comparison value really wants to be a float) @@ -810,7 +814,7 @@ def FADDS : AForm_2<59, 21, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB), "fadds $FRT, $FRA, $FRB", - []>; + [(set F4RC:$FRT, (fadd F4RC:$FRA, F4RC:$FRB))]>; def FDIV : AForm_2<63, 18, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB), "fdiv $FRT, $FRA, $FRB", @@ -818,7 +822,7 @@ def FDIVS : AForm_2<59, 18, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB), "fdivs $FRT, $FRA, $FRB", - []>; + [(set F4RC:$FRT, (fdiv F4RC:$FRA, F4RC:$FRB))]>; def FMUL : AForm_3<63, 25, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB), "fmul $FRT, $FRA, $FRB", @@ -826,7 +830,7 @@ def FMULS : AForm_3<59, 25, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB), "fmuls $FRT, $FRA, $FRB", - []>; + [(set F4RC:$FRT, (fmul F4RC:$FRA, F4RC:$FRB))]>; def FSUB : AForm_2<63, 20, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB), "fsub $FRT, $FRA, $FRB", @@ -834,7 +838,7 @@ def FSUBS : AForm_2<59, 20, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB), "fsubs $FRT, $FRA, $FRB", - []>; + [(set F4RC:$FRT, (fsub F4RC:$FRA, F4RC:$FRB))]>; // M-Form instructions. rotate and mask instructions. // From lattner at cs.uiuc.edu Sun Oct 2 11:28:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 11:28:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/InstrSched/SchedGraph.cpp Message-ID: <200510021628.LAA21220@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/InstrSched: SchedGraph.cpp updated: 1.71 -> 1.72 --- Log message: silence a warning --- Diffs of the changes: (+1 -1) SchedGraph.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/SparcV9/InstrSched/SchedGraph.cpp diff -u llvm/lib/Target/SparcV9/InstrSched/SchedGraph.cpp:1.71 llvm/lib/Target/SparcV9/InstrSched/SchedGraph.cpp:1.72 --- llvm/lib/Target/SparcV9/InstrSched/SchedGraph.cpp:1.71 Wed Jul 27 01:12:34 2005 +++ llvm/lib/Target/SparcV9/InstrSched/SchedGraph.cpp Sun Oct 2 11:27:59 2005 @@ -503,7 +503,7 @@ // (only if the node is not already on the callDepVec!) if (callDepNodeVec.size() == 0 || callDepNodeVec.back() != node) { - unsigned rcid; + unsigned rcid = 0; int regInClass = target.getRegInfo()->getClassRegNum(regNum, rcid); if (target.getRegInfo()->getMachineRegClass(rcid) ->isRegVolatile(regInClass)) From lattner at cs.uiuc.edu Sun Oct 2 11:29:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 11:29:48 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200510021629.LAA21277@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.180 -> 1.181 --- Log message: silence some warnings --- Diffs of the changes: (+2 -3) X86ISelPattern.cpp | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.180 llvm/lib/Target/X86/X86ISelPattern.cpp:1.181 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.180 Wed Sep 28 17:29:17 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Sun Oct 2 11:29:36 2005 @@ -2219,8 +2219,7 @@ unsigned ISel::SelectExpr(SDOperand N) { unsigned Result; - unsigned Tmp1, Tmp2, Tmp3; - unsigned Opc = 0; + unsigned Tmp1 = 0, Tmp2 = 0, Tmp3 = 0, Opc = 0; SDNode *Node = N.Val; SDOperand Op0, Op1; @@ -4148,7 +4147,7 @@ void ISel::Select(SDOperand N) { - unsigned Tmp1, Tmp2, Opc; + unsigned Tmp1 = 0, Tmp2 = 0, Opc = 0; if (!ExprMap.insert(std::make_pair(N, 1)).second) return; // Already selected. From lattner at cs.uiuc.edu Sun Oct 2 11:31:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 11:31:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200510021631.LAA21344@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.31 -> 1.32 --- Log message: silence a bogus warning --- Diffs of the changes: (+1 -1) ScheduleDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.31 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.32 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.31 Sun Oct 2 02:10:55 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Sun Oct 2 11:30:51 2005 @@ -1186,7 +1186,7 @@ } break; case ISD::CopyToReg: { - SDOperand FlagOp; + SDOperand FlagOp; FlagOp.ResNo = 0; if (Op.getNumOperands() == 4) { FlagOp = Op.getOperand(3); } From lattner at cs.uiuc.edu Sun Oct 2 12:49:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 12:49:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200510021749.MAA21529@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.188 -> 1.189 --- Log message: Fix a problem where the legalizer would run out of stack space on extremely large basic blocks because it was purely recursive. This switches it to an iterative/recursive hybrid. --- Diffs of the changes: (+36 -9) LegalizeDAG.cpp | 45 ++++++++++++++++++++++++++++++++++++--------- 1 files changed, 36 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.188 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.189 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.188 Thu Sep 29 01:44:39 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sun Oct 2 12:49:46 2005 @@ -380,8 +380,43 @@ void SelectionDAGLegalize::LegalizeDAG() { + // The legalize process is inherently a bottom-up recursive process (users + // legalize their uses before themselves). Given infinite stack space, we + // could just start legalizing on the root and traverse the whole graph. In + // practice however, this causes us to run out of stack space on large basic + // blocks. To avoid this problem, legalize the entry node, then all its uses + // iteratively instead of recursively. + std::vector Worklist; + Worklist.push_back(DAG.getEntryNode()); + + while (!Worklist.empty()) { + SDOperand Node = Worklist.back(); + Worklist.pop_back(); + + if (LegalizedNodes.count(Node)) continue; + + for (SDNode::use_iterator UI = Node.Val->use_begin(), + E = Node.Val->use_end(); UI != E; ++UI) { + // Scan the values. If this use has a value that is a token chain, add it + // to the worklist. + SDNode *User = *UI; + for (unsigned i = 0, e = User->getNumValues(); i != e; ++i) + if (User->getValueType(i) == MVT::Other) { + Worklist.push_back(SDOperand(User, i)); + break; + } + } + + // Finally, legalize this node. + LegalizeOp(Node); + } + + + // Finally, legalize from the root up, to make sure we have legalized + // everything possible. SDOperand OldRoot = DAG.getRoot(); SDOperand NewRoot = LegalizeOp(OldRoot); + DAG.setRoot(NewRoot); ExpandedNodes.clear(); @@ -588,17 +623,9 @@ Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. // Do not try to legalize the target-specific arguments (#1+) Tmp2 = Node->getOperand(0); - if (Tmp1 != Tmp2) { + if (Tmp1 != Tmp2) Node->setAdjCallChain(Tmp1); - // If moving the operand from pointing to Tmp2 dropped its use count to 1, - // this will cause the maps used to memoize results to get confused. - // Create and add a dummy use, just to increase its use count. This will - // be removed at the end of legalize when dead nodes are removed. - if (Tmp2.Val->hasOneUse()) - DAG.getNode(ISD::PCMARKER, MVT::Other, Tmp2, - DAG.getConstant(0, MVT::i32)); - } // Note that we do not create new CALLSEQ_DOWN/UP nodes here. These // nodes are treated specially and are mutated in place. This makes the dag // legalization process more efficient and also makes libcall insertion From lattner at cs.uiuc.edu Sun Oct 2 14:47:14 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 14:47:14 -0500 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Benchmarks/Olden/Makefile Message-ID: <200510021947.OAA22120@zion.cs.uiuc.edu> Changes in directory llvm-test/MultiSource/Benchmarks/Olden: Makefile updated: 1.5 -> 1.6 --- Log message: Reorder this line so that it matches the nightly tester gnuplot scripts, which was causing us to get the wrong labels on lines. --- Diffs of the changes: (+4 -1) Makefile | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm-test/MultiSource/Benchmarks/Olden/Makefile diff -u llvm-test/MultiSource/Benchmarks/Olden/Makefile:1.5 llvm-test/MultiSource/Benchmarks/Olden/Makefile:1.6 --- llvm-test/MultiSource/Benchmarks/Olden/Makefile:1.5 Wed Sep 1 09:33:25 2004 +++ llvm-test/MultiSource/Benchmarks/Olden/Makefile Sun Oct 2 14:47:03 2005 @@ -1,7 +1,10 @@ # MultiSource/Olden Makefile: Build all subdirectories automatically LEVEL = ../../.. -PARALLEL_DIRS := bh em3d mst power tsp bisort health perimeter treeadd voronoi + +## NOTE: This must remain sorted, so that the labels in the nightly tester +## gnuplot scripts are correct. +PARALLEL_DIRS := bh bisort em3d health mst perimeter power treeadd tsp voronoi include $(LEVEL)/Makefile.programs From lattner at cs.uiuc.edu Sun Oct 2 15:53:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 15:53:32 -0500 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Benchmarks/Olden/Makefile Message-ID: <200510022053.PAA22372@zion.cs.uiuc.edu> Changes in directory llvm-test/MultiSource/Benchmarks/Olden: Makefile updated: 1.6 -> 1.7 --- Log message: Don't make the nightly tester colors change all around. We don't want bisort and em3d's lines to swap datapoints. --- Diffs of the changes: (+2 -3) Makefile | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) Index: llvm-test/MultiSource/Benchmarks/Olden/Makefile diff -u llvm-test/MultiSource/Benchmarks/Olden/Makefile:1.6 llvm-test/MultiSource/Benchmarks/Olden/Makefile:1.7 --- llvm-test/MultiSource/Benchmarks/Olden/Makefile:1.6 Sun Oct 2 14:47:03 2005 +++ llvm-test/MultiSource/Benchmarks/Olden/Makefile Sun Oct 2 15:53:20 2005 @@ -2,9 +2,8 @@ LEVEL = ../../.. -## NOTE: This must remain sorted, so that the labels in the nightly tester +## NOTE: This must remain in this oder, so that the labels in the nightly tester ## gnuplot scripts are correct. -PARALLEL_DIRS := bh bisort em3d health mst perimeter power treeadd tsp voronoi - +PARALLEL_DIRS := bh em3d mst power tsp bisort health perimeter treeadd voronoi include $(LEVEL)/Makefile.programs From lattner at cs.uiuc.edu Sun Oct 2 16:51:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 16:51:50 -0500 Subject: [llvm-commits] CVS: llvm/utils/NightlyTest.gnuplot Message-ID: <200510022151.QAA22675@zion.cs.uiuc.edu> Changes in directory llvm/utils: NightlyTest.gnuplot updated: 1.12 -> 1.13 --- Log message: put the right labels on the data --- Diffs of the changes: (+96 -96) NightlyTest.gnuplot | 192 ++++++++++++++++++++++++++-------------------------- 1 files changed, 96 insertions(+), 96 deletions(-) Index: llvm/utils/NightlyTest.gnuplot diff -u llvm/utils/NightlyTest.gnuplot:1.12 llvm/utils/NightlyTest.gnuplot:1.13 --- llvm/utils/NightlyTest.gnuplot:1.12 Tue Nov 23 00:51:14 2004 +++ llvm/utils/NightlyTest.gnuplot Sun Oct 2 16:51:38 2005 @@ -44,14 +44,14 @@ set ylabel "CBE compiled execution time (s)" plot "running_Olden_cbe_time.txt" u 1:2 t '' with lines, \ "running_Olden_cbe_time.txt" u 1:2 t "bh" with lines, \ - "running_Olden_cbe_time.txt" u 1:3 t "bisort" with lines, \ - "running_Olden_cbe_time.txt" u 1:4 t "em3d" with lines, \ - "running_Olden_cbe_time.txt" u 1:5 t "health" with lines, \ - "running_Olden_cbe_time.txt" u 1:6 t "mst" with lines, \ - "running_Olden_cbe_time.txt" u 1:7 t "perimeter" with lines, \ - "running_Olden_cbe_time.txt" u 1:8 t "power" with lines, \ - "running_Olden_cbe_time.txt" u 1:9 t "treeadd" with lines, \ - "running_Olden_cbe_time.txt" u 1:10 t "tsp" with lines, \ + "running_Olden_cbe_time.txt" u 1:3 t "em3d" with lines, \ + "running_Olden_cbe_time.txt" u 1:4 t "mst" with lines, \ + "running_Olden_cbe_time.txt" u 1:5 t "power" with lines, \ + "running_Olden_cbe_time.txt" u 1:6 t "tsp" with lines, \ + "running_Olden_cbe_time.txt" u 1:7 t "bisort" with lines, \ + "running_Olden_cbe_time.txt" u 1:8 t "health" with lines, \ + "running_Olden_cbe_time.txt" u 1:9 t "perimeter" with lines, \ + "running_Olden_cbe_time.txt" u 1:10 t "treeadd" with lines, \ "running_Olden_cbe_time.txt" u 1:11 t "voronoi" \ with lines @@ -61,14 +61,14 @@ set output "running_Olden_cbe_time_large.png" plot "running_Olden_cbe_time.txt" u 1:2 t '' with lines, \ "running_Olden_cbe_time.txt" u 1:2 t "bh" with lines, \ - "running_Olden_cbe_time.txt" u 1:3 t "bisort" with lines, \ - "running_Olden_cbe_time.txt" u 1:4 t "em3d" with lines, \ - "running_Olden_cbe_time.txt" u 1:5 t "health" with lines, \ - "running_Olden_cbe_time.txt" u 1:6 t "mst" with lines, \ - "running_Olden_cbe_time.txt" u 1:7 t "perimeter" with lines, \ - "running_Olden_cbe_time.txt" u 1:8 t "power" with lines, \ - "running_Olden_cbe_time.txt" u 1:9 t "treeadd" with lines, \ - "running_Olden_cbe_time.txt" u 1:10 t "tsp" with lines, \ + "running_Olden_cbe_time.txt" u 1:3 t "em3d" with lines, \ + "running_Olden_cbe_time.txt" u 1:4 t "mst" with lines, \ + "running_Olden_cbe_time.txt" u 1:5 t "power" with lines, \ + "running_Olden_cbe_time.txt" u 1:6 t "tsp" with lines, \ + "running_Olden_cbe_time.txt" u 1:7 t "bisort" with lines, \ + "running_Olden_cbe_time.txt" u 1:8 t "health" with lines, \ + "running_Olden_cbe_time.txt" u 1:9 t "perimeter" with lines, \ + "running_Olden_cbe_time.txt" u 1:10 t "treeadd" with lines, \ "running_Olden_cbe_time.txt" u 1:11 t "voronoi" \ with lines @@ -81,14 +81,14 @@ set ylabel "JIT execution time (s)" plot "running_Olden_jit_time.txt" u 1:2 t '' with lines, \ "running_Olden_jit_time.txt" u 1:2 t "bh" with lines, \ - "running_Olden_jit_time.txt" u 1:3 t "bisort" with lines, \ - "running_Olden_jit_time.txt" u 1:4 t "em3d" with lines, \ - "running_Olden_jit_time.txt" u 1:5 t "health" with lines, \ - "running_Olden_jit_time.txt" u 1:6 t "mst" with lines, \ - "running_Olden_jit_time.txt" u 1:7 t "perimeter" with lines, \ - "running_Olden_jit_time.txt" u 1:8 t "power" with lines, \ - "running_Olden_jit_time.txt" u 1:9 t "treeadd" with lines, \ - "running_Olden_jit_time.txt" u 1:10 t "tsp" with lines, \ + "running_Olden_jit_time.txt" u 1:3 t "em3d" with lines, \ + "running_Olden_jit_time.txt" u 1:4 t "mst" with lines, \ + "running_Olden_jit_time.txt" u 1:5 t "power" with lines, \ + "running_Olden_jit_time.txt" u 1:6 t "tsp" with lines, \ + "running_Olden_jit_time.txt" u 1:7 t "bisort" with lines, \ + "running_Olden_jit_time.txt" u 1:8 t "health" with lines, \ + "running_Olden_jit_time.txt" u 1:9 t "perimeter" with lines, \ + "running_Olden_jit_time.txt" u 1:10 t "treeadd" with lines, \ "running_Olden_jit_time.txt" u 1:11 t "voronoi" \ with lines @@ -98,14 +98,14 @@ set output "running_Olden_jit_time_large.png" plot "running_Olden_jit_time.txt" u 1:2 t '' with lines, \ "running_Olden_jit_time.txt" u 1:2 t "bh" with lines, \ - "running_Olden_jit_time.txt" u 1:3 t "bisort" with lines, \ - "running_Olden_jit_time.txt" u 1:4 t "em3d" with lines, \ - "running_Olden_jit_time.txt" u 1:5 t "health" with lines, \ - "running_Olden_jit_time.txt" u 1:6 t "mst" with lines, \ - "running_Olden_jit_time.txt" u 1:7 t "perimeter" with lines, \ - "running_Olden_jit_time.txt" u 1:8 t "power" with lines, \ - "running_Olden_jit_time.txt" u 1:9 t "treeadd" with lines, \ - "running_Olden_jit_time.txt" u 1:10 t "tsp" with lines, \ + "running_Olden_jit_time.txt" u 1:3 t "em3d" with lines, \ + "running_Olden_jit_time.txt" u 1:4 t "mst" with lines, \ + "running_Olden_jit_time.txt" u 1:5 t "power" with lines, \ + "running_Olden_jit_time.txt" u 1:6 t "tsp" with lines, \ + "running_Olden_jit_time.txt" u 1:7 t "bisort" with lines, \ + "running_Olden_jit_time.txt" u 1:8 t "health" with lines, \ + "running_Olden_jit_time.txt" u 1:9 t "perimeter" with lines, \ + "running_Olden_jit_time.txt" u 1:10 t "treeadd" with lines, \ "running_Olden_jit_time.txt" u 1:11 t "voronoi" \ with lines @@ -118,14 +118,14 @@ set ylabel "LLC compiled execution time (s)" plot "running_Olden_llc_time.txt" u 1:2 t '' with lines, \ "running_Olden_llc_time.txt" u 1:2 t "bh" with lines, \ - "running_Olden_llc_time.txt" u 1:3 t "bisort" with lines, \ - "running_Olden_llc_time.txt" u 1:4 t "em3d" with lines, \ - "running_Olden_llc_time.txt" u 1:5 t "health" with lines, \ - "running_Olden_llc_time.txt" u 1:6 t "mst" with lines, \ - "running_Olden_llc_time.txt" u 1:7 t "perimeter" with lines, \ - "running_Olden_llc_time.txt" u 1:8 t "power" with lines, \ - "running_Olden_llc_time.txt" u 1:9 t "treeadd" with lines, \ - "running_Olden_llc_time.txt" u 1:10 t "tsp" with lines, \ + "running_Olden_llc_time.txt" u 1:3 t "em3d" with lines, \ + "running_Olden_llc_time.txt" u 1:4 t "mst" with lines, \ + "running_Olden_llc_time.txt" u 1:5 t "power" with lines, \ + "running_Olden_llc_time.txt" u 1:6 t "tsp" with lines, \ + "running_Olden_llc_time.txt" u 1:7 t "bisort" with lines, \ + "running_Olden_llc_time.txt" u 1:8 t "health" with lines, \ + "running_Olden_llc_time.txt" u 1:9 t "perimeter" with lines, \ + "running_Olden_llc_time.txt" u 1:10 t "treeadd" with lines, \ "running_Olden_llc_time.txt" u 1:11 t "voronoi" \ with lines @@ -135,14 +135,14 @@ set output "running_Olden_llc_time_large.png" plot "running_Olden_llc_time.txt" u 1:2 t '' with lines, \ "running_Olden_llc_time.txt" u 1:2 t "bh" with lines, \ - "running_Olden_llc_time.txt" u 1:3 t "bisort" with lines, \ - "running_Olden_llc_time.txt" u 1:4 t "em3d" with lines, \ - "running_Olden_llc_time.txt" u 1:5 t "health" with lines, \ - "running_Olden_llc_time.txt" u 1:6 t "mst" with lines, \ - "running_Olden_llc_time.txt" u 1:7 t "perimeter" with lines, \ - "running_Olden_llc_time.txt" u 1:8 t "power" with lines, \ - "running_Olden_llc_time.txt" u 1:9 t "treeadd" with lines, \ - "running_Olden_llc_time.txt" u 1:10 t "tsp" with lines, \ + "running_Olden_llc_time.txt" u 1:3 t "em3d" with lines, \ + "running_Olden_llc_time.txt" u 1:4 t "mst" with lines, \ + "running_Olden_llc_time.txt" u 1:5 t "power" with lines, \ + "running_Olden_llc_time.txt" u 1:6 t "tsp" with lines, \ + "running_Olden_llc_time.txt" u 1:7 t "bisort" with lines, \ + "running_Olden_llc_time.txt" u 1:8 t "health" with lines, \ + "running_Olden_llc_time.txt" u 1:9 t "perimeter" with lines, \ + "running_Olden_llc_time.txt" u 1:10 t "treeadd" with lines, \ "running_Olden_llc_time.txt" u 1:11 t "voronoi" \ with lines @@ -156,14 +156,14 @@ set ylabel "Time to run the optimizer (s)" plot "running_Olden_opt_time.txt" u 1:2 t '' with lines, \ "running_Olden_opt_time.txt" u 1:2 t "bh" with lines, \ - "running_Olden_opt_time.txt" u 1:3 t "bisort" with lines, \ - "running_Olden_opt_time.txt" u 1:4 t "em3d" with lines, \ - "running_Olden_opt_time.txt" u 1:5 t "health" with lines, \ - "running_Olden_opt_time.txt" u 1:6 t "mst" with lines, \ - "running_Olden_opt_time.txt" u 1:7 t "perimeter" with lines, \ - "running_Olden_opt_time.txt" u 1:8 t "power" with lines, \ - "running_Olden_opt_time.txt" u 1:9 t "treeadd" with lines, \ - "running_Olden_opt_time.txt" u 1:10 t "tsp" with lines, \ + "running_Olden_opt_time.txt" u 1:3 t "em3d" with lines, \ + "running_Olden_opt_time.txt" u 1:4 t "mst" with lines, \ + "running_Olden_opt_time.txt" u 1:5 t "power" with lines, \ + "running_Olden_opt_time.txt" u 1:6 t "tsp" with lines, \ + "running_Olden_opt_time.txt" u 1:7 t "bisort" with lines, \ + "running_Olden_opt_time.txt" u 1:8 t "health" with lines, \ + "running_Olden_opt_time.txt" u 1:9 t "perimeter" with lines, \ + "running_Olden_opt_time.txt" u 1:10 t "treeadd" with lines, \ "running_Olden_opt_time.txt" u 1:11 t "voronoi" \ with lines @@ -173,14 +173,14 @@ set output "running_Olden_opt_time_large.png" plot "running_Olden_opt_time.txt" u 1:2 t '' with lines, \ "running_Olden_opt_time.txt" u 1:2 t "bh" with lines, \ - "running_Olden_opt_time.txt" u 1:3 t "bisort" with lines, \ - "running_Olden_opt_time.txt" u 1:4 t "em3d" with lines, \ - "running_Olden_opt_time.txt" u 1:5 t "health" with lines, \ - "running_Olden_opt_time.txt" u 1:6 t "mst" with lines, \ - "running_Olden_opt_time.txt" u 1:7 t "perimeter" with lines, \ - "running_Olden_opt_time.txt" u 1:8 t "power" with lines, \ - "running_Olden_opt_time.txt" u 1:9 t "treeadd" with lines, \ - "running_Olden_opt_time.txt" u 1:10 t "tsp" with lines, \ + "running_Olden_opt_time.txt" u 1:3 t "em3d" with lines, \ + "running_Olden_opt_time.txt" u 1:4 t "mst" with lines, \ + "running_Olden_opt_time.txt" u 1:5 t "power" with lines, \ + "running_Olden_opt_time.txt" u 1:6 t "tsp" with lines, \ + "running_Olden_opt_time.txt" u 1:7 t "bisort" with lines, \ + "running_Olden_opt_time.txt" u 1:8 t "health" with lines, \ + "running_Olden_opt_time.txt" u 1:9 t "perimeter" with lines, \ + "running_Olden_opt_time.txt" u 1:10 t "treeadd" with lines, \ "running_Olden_opt_time.txt" u 1:11 t "voronoi" \ with lines @@ -194,14 +194,14 @@ set ylabel "Program machine code size (bytes)" plot "running_Olden_machcode.txt" u 1:2 t '' with lines, \ "running_Olden_machcode.txt" u 1:2 t "bh" with lines, \ - "running_Olden_machcode.txt" u 1:3 t "bisort" with lines, \ - "running_Olden_machcode.txt" u 1:4 t "em3d" with lines, \ - "running_Olden_machcode.txt" u 1:5 t "health" with lines, \ - "running_Olden_machcode.txt" u 1:6 t "mst" with lines, \ - "running_Olden_machcode.txt" u 1:7 t "perimeter" with lines, \ - "running_Olden_machcode.txt" u 1:8 t "power" with lines, \ - "running_Olden_machcode.txt" u 1:9 t "treeadd" with lines, \ - "running_Olden_machcode.txt" u 1:10 t "tsp" with lines, \ + "running_Olden_machcode.txt" u 1:3 t "em3d" with lines, \ + "running_Olden_machcode.txt" u 1:4 t "mst" with lines, \ + "running_Olden_machcode.txt" u 1:5 t "power" with lines, \ + "running_Olden_machcode.txt" u 1:6 t "tsp" with lines, \ + "running_Olden_machcode.txt" u 1:7 t "bisort" with lines, \ + "running_Olden_machcode.txt" u 1:8 t "health" with lines, \ + "running_Olden_machcode.txt" u 1:9 t "perimeter" with lines, \ + "running_Olden_machcode.txt" u 1:10 t "treeadd" with lines, \ "running_Olden_machcode.txt" u 1:11 t "voronoi" \ with lines @@ -211,14 +211,14 @@ set output "running_Olden_machcode_large.png" plot "running_Olden_machcode.txt" u 1:2 t '' with lines, \ "running_Olden_machcode.txt" u 1:2 t "bh" with lines, \ - "running_Olden_machcode.txt" u 1:3 t "bisort" with lines, \ - "running_Olden_machcode.txt" u 1:4 t "em3d" with lines, \ - "running_Olden_machcode.txt" u 1:5 t "health" with lines, \ - "running_Olden_machcode.txt" u 1:6 t "mst" with lines, \ - "running_Olden_machcode.txt" u 1:7 t "perimeter" with lines, \ - "running_Olden_machcode.txt" u 1:8 t "power" with lines, \ - "running_Olden_machcode.txt" u 1:9 t "treeadd" with lines, \ - "running_Olden_machcode.txt" u 1:10 t "tsp" with lines, \ + "running_Olden_machcode.txt" u 1:3 t "em3d" with lines, \ + "running_Olden_machcode.txt" u 1:4 t "mst" with lines, \ + "running_Olden_machcode.txt" u 1:5 t "power" with lines, \ + "running_Olden_machcode.txt" u 1:6 t "tsp" with lines, \ + "running_Olden_machcode.txt" u 1:7 t "bisort" with lines, \ + "running_Olden_machcode.txt" u 1:8 t "health" with lines, \ + "running_Olden_machcode.txt" u 1:9 t "perimeter" with lines, \ + "running_Olden_machcode.txt" u 1:10 t "treeadd" with lines, \ "running_Olden_machcode.txt" u 1:11 t "voronoi" \ with lines @@ -232,14 +232,14 @@ set ylabel "Program bytecode size (bytes)" plot "running_Olden_bytecode.txt" u 1:2 t '' with lines, \ "running_Olden_bytecode.txt" u 1:2 t "bh" with lines, \ - "running_Olden_bytecode.txt" u 1:3 t "bisort" with lines, \ - "running_Olden_bytecode.txt" u 1:4 t "em3d" with lines, \ - "running_Olden_bytecode.txt" u 1:5 t "health" with lines, \ - "running_Olden_bytecode.txt" u 1:6 t "mst" with lines, \ - "running_Olden_bytecode.txt" u 1:7 t "perimeter" with lines, \ - "running_Olden_bytecode.txt" u 1:8 t "power" with lines, \ - "running_Olden_bytecode.txt" u 1:9 t "treeadd" with lines, \ - "running_Olden_bytecode.txt" u 1:10 t "tsp" with lines, \ + "running_Olden_bytecode.txt" u 1:3 t "em3d" with lines, \ + "running_Olden_bytecode.txt" u 1:4 t "mst" with lines, \ + "running_Olden_bytecode.txt" u 1:5 t "power" with lines, \ + "running_Olden_bytecode.txt" u 1:6 t "tsp" with lines, \ + "running_Olden_bytecode.txt" u 1:7 t "bisort" with lines, \ + "running_Olden_bytecode.txt" u 1:8 t "health" with lines, \ + "running_Olden_bytecode.txt" u 1:9 t "perimeter" with lines, \ + "running_Olden_bytecode.txt" u 1:10 t "treeadd" with lines, \ "running_Olden_bytecode.txt" u 1:11 t "voronoi" \ with lines @@ -249,13 +249,13 @@ set output "running_Olden_bytecode_large.png" plot "running_Olden_bytecode.txt" u 1:2 t '' with lines, \ "running_Olden_bytecode.txt" u 1:2 t "bh" with lines, \ - "running_Olden_bytecode.txt" u 1:3 t "bisort" with lines, \ - "running_Olden_bytecode.txt" u 1:4 t "em3d" with lines, \ - "running_Olden_bytecode.txt" u 1:5 t "health" with lines, \ - "running_Olden_bytecode.txt" u 1:6 t "mst" with lines, \ - "running_Olden_bytecode.txt" u 1:7 t "perimeter" with lines, \ - "running_Olden_bytecode.txt" u 1:8 t "power" with lines, \ - "running_Olden_bytecode.txt" u 1:9 t "treeadd" with lines, \ - "running_Olden_bytecode.txt" u 1:10 t "tsp" with lines, \ + "running_Olden_bytecode.txt" u 1:3 t "em3d" with lines, \ + "running_Olden_bytecode.txt" u 1:4 t "mst" with lines, \ + "running_Olden_bytecode.txt" u 1:5 t "power" with lines, \ + "running_Olden_bytecode.txt" u 1:6 t "tsp" with lines, \ + "running_Olden_bytecode.txt" u 1:7 t "bisort" with lines, \ + "running_Olden_bytecode.txt" u 1:8 t "health" with lines, \ + "running_Olden_bytecode.txt" u 1:9 t "perimeter" with lines, \ + "running_Olden_bytecode.txt" u 1:10 t "treeadd" with lines, \ "running_Olden_bytecode.txt" u 1:11 t "voronoi" \ with lines From lattner at cs.uiuc.edu Sun Oct 2 19:21:36 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 19:21:36 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200510030021.TAA23273@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.63 -> 1.64 --- Log message: This member can be const too --- Diffs of the changes: (+1 -1) MRegisterInfo.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.63 llvm/include/llvm/Target/MRegisterInfo.h:1.64 --- llvm/include/llvm/Target/MRegisterInfo.h:1.63 Sun Oct 2 01:23:19 2005 +++ llvm/include/llvm/Target/MRegisterInfo.h Sun Oct 2 19:21:25 2005 @@ -45,7 +45,7 @@ typedef const unsigned* const_iterator; private: - MVT::ValueType VT; + const MVT::ValueType VT; const unsigned RegSize, Alignment; // Size & Alignment of register in bytes const iterator RegsBegin, RegsEnd; public: From lattner at cs.uiuc.edu Sun Oct 2 19:32:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 19:32:04 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200510030032.TAA23344@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.59 -> 1.60 --- Log message: when checking if we should move a split edge block outside of a loop, check the presplit pred, not the post-split pred. This was causing us to make the wrong decision in some cases, leaving the critical edge block in the loop. --- Diffs of the changes: (+6 -7) LoopStrengthReduce.cpp | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.59 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.60 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.59 Tue Sep 27 16:10:32 2005 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Sun Oct 2 19:31:52 2005 @@ -462,20 +462,19 @@ // code on all predecessor/successor paths. We do this unless this is the // canonical backedge for this loop, as this can make some inserted code // be in an illegal position. - if (e != 1 && - PN->getIncomingBlock(i)->getTerminator()->getNumSuccessors() > 1 && - (PN->getParent() != L->getHeader() || - !L->contains(PN->getIncomingBlock(i)))) { + BasicBlock *PHIPred = PN->getIncomingBlock(i); + if (e != 1 && PHIPred->getTerminator()->getNumSuccessors() > 1 && + (PN->getParent() != L->getHeader() || !L->contains(PHIPred))) { + // First step, split the critical edge. - SplitCriticalEdge(PN->getIncomingBlock(i), PN->getParent(), P); + SplitCriticalEdge(PHIPred, PN->getParent(), P); // Next step: move the basic block. In particular, if the PHI node // is outside of the loop, and PredTI is in the loop, we want to // move the block to be immediately before the PHI block, not // immediately after PredTI. - if (L->contains(PN->getIncomingBlock(i)) && - !L->contains(PN->getParent())) { + if (L->contains(PHIPred) && !L->contains(PN->getParent())) { BasicBlock *NewBB = PN->getIncomingBlock(i); NewBB->moveBefore(PN->getParent()); } From lattner at cs.uiuc.edu Sun Oct 2 19:37:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 19:37:44 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200510030037.TAA23405@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.60 -> 1.61 --- Log message: This break is bogus and I have no idea why it was there. Basically it prevents memoizing code when IV's are used by phinodes outside of loops. In a simple example, we were getting this code before (note that r6 and r7 are isomorphic IV's): li r6, 0 or r7, r6, r6 LBB_test_3: ; no_exit lwz r2, 0(r3) cmpw cr0, r2, r5 or r2, r7, r7 beq cr0, LBB_test_5 ; loopexit LBB_test_4: ; endif addi r2, r7, 1 addi r7, r7, 1 addi r3, r3, 4 addi r6, r6, 1 cmpw cr0, r6, r4 blt cr0, LBB_test_3 ; no_exit Now we get: li r6, 0 LBB_test_3: ; no_exit or r2, r6, r6 lwz r6, 0(r3) cmpw cr0, r6, r5 beq cr0, LBB_test_6 ; loopexit LBB_test_4: ; endif addi r3, r3, 4 addi r6, r2, 1 cmpw cr0, r6, r4 blt cr0, LBB_test_3 ; no_exit this was noticed in em3d. --- Diffs of the changes: (+0 -1) LoopStrengthReduce.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.60 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.61 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.60 Sun Oct 2 19:31:52 2005 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Sun Oct 2 19:37:33 2005 @@ -478,7 +478,6 @@ BasicBlock *NewBB = PN->getIncomingBlock(i); NewBB->moveBefore(PN->getParent()); } - break; } Value *&Code = InsertedCode[PN->getIncomingBlock(i)]; From lattner at cs.uiuc.edu Sun Oct 2 20:04:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 20:04:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200510030104.UAA23536@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.61 -> 1.62 --- Log message: Refactor some code into a function --- Diffs of the changes: (+23 -7) LoopStrengthReduce.cpp | 30 +++++++++++++++++++++++------- 1 files changed, 23 insertions(+), 7 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.61 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.62 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.61 Sun Oct 2 19:37:33 2005 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Sun Oct 2 20:04:44 2005 @@ -310,6 +310,26 @@ return true; } +/// IVUseShouldUsePostIncValue - We have discovered a "User" of an IV expression +/// and now we need to decide whether the user should use the preinc or post-inc +/// value. If this user should use the post-inc version of the IV, return true. +/// +/// Choosing wrong here can break dominance properties (if we choose to use the +/// post-inc value when we cannot) or it can end up adding extra live-ranges to +/// the loop, resulting in reg-reg copies (if we use the pre-inc value when we +/// should use the post-inc value). +static bool IVUseShouldUsePostIncValue(Instruction *User, Instruction *IV, + Loop *L, DominatorSet *DS) { + // If the user is in the loop, use the preinc value. + if (L->contains(User->getParent())) return false; + + // Ok, the user is outside of the loop. If it is not dominated by the latch + // block, we have to use the preincremented value. + return DS->dominates(L->getLoopLatch(), User->getParent()); +} + + + /// AddUsersIfInteresting - Inspect the specified instruction. If it is a /// reducible SCEV, recursively add its users to the IVUsesByStride set and /// return true. Otherwise, return false. @@ -353,18 +373,14 @@ // Okay, we found a user that we cannot reduce. Analyze the instruction // and decide what to do with it. If we are a use inside of the loop, use // the value before incrementation, otherwise use it after incrementation. - if (L->contains(User->getParent()) || - // Alternatively, if we are a use outside of the loop, but is not - // dominated by the latch block, we have to use the preincremented - // value. - !DS->dominates(L->getLoopLatch(), User->getParent())) { - IVUsesByStride[Stride].addUser(Start, User, I); - } else { + if (IVUseShouldUsePostIncValue(User, I, L, DS)) { // The value used will be incremented by the stride more than we are // expecting, so subtract this off. SCEVHandle NewStart = SCEV::getMinusSCEV(Start, Stride); IVUsesByStride[Stride].addUser(NewStart, User, I); IVUsesByStride[Stride].Users.back().isUseOfPostIncrementedValue = true; + } else { + IVUsesByStride[Stride].addUser(Start, User, I); } } } From lattner at cs.uiuc.edu Sun Oct 2 21:50:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 21:50:16 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200510030250.VAA23814@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.62 -> 1.63 --- Log message: Make IVUseShouldUsePostIncValue more aggressive when the use is a PHI. In particular, it should realize that phi's use their values in the pred block not the phi block itself. This change turns our em3d loop from this: _test: cmpwi cr0, r4, 0 bgt cr0, LBB_test_2 ; entry.no_exit_crit_edge LBB_test_1: ; entry.loopexit_crit_edge li r2, 0 b LBB_test_6 ; loopexit LBB_test_2: ; entry.no_exit_crit_edge li r6, 0 LBB_test_3: ; no_exit or r2, r6, r6 lwz r6, 0(r3) cmpw cr0, r6, r5 beq cr0, LBB_test_6 ; loopexit LBB_test_4: ; endif addi r3, r3, 4 addi r6, r2, 1 cmpw cr0, r6, r4 blt cr0, LBB_test_3 ; no_exit LBB_test_5: ; endif.loopexit.loopexit_crit_edge addi r3, r2, 1 blr LBB_test_6: ; loopexit or r3, r2, r2 blr into: _test: cmpwi cr0, r4, 0 bgt cr0, LBB_test_2 ; entry.no_exit_crit_edge LBB_test_1: ; entry.loopexit_crit_edge li r2, 0 b LBB_test_5 ; loopexit LBB_test_2: ; entry.no_exit_crit_edge li r6, 0 LBB_test_3: ; no_exit lwz r2, 0(r3) cmpw cr0, r2, r5 or r2, r6, r6 beq cr0, LBB_test_5 ; loopexit LBB_test_4: ; endif addi r3, r3, 4 addi r6, r6, 1 cmpw cr0, r6, r4 or r2, r6, r6 blt cr0, LBB_test_3 ; no_exit LBB_test_5: ; loopexit or r3, r2, r2 blr Unfortunately, this is actually worse code, because the register coallescer is getting confused somehow. If it were doing its job right, it could turn the code into this: _test: cmpwi cr0, r4, 0 bgt cr0, LBB_test_2 ; entry.no_exit_crit_edge LBB_test_1: ; entry.loopexit_crit_edge li r6, 0 b LBB_test_5 ; loopexit LBB_test_2: ; entry.no_exit_crit_edge li r6, 0 LBB_test_3: ; no_exit lwz r2, 0(r3) cmpw cr0, r2, r5 beq cr0, LBB_test_5 ; loopexit LBB_test_4: ; endif addi r3, r3, 4 addi r6, r6, 1 cmpw cr0, r6, r4 blt cr0, LBB_test_3 ; no_exit LBB_test_5: ; loopexit or r3, r6, r6 blr ... which I'll work on next. :) --- Diffs of the changes: (+38 -6) LoopStrengthReduce.cpp | 44 ++++++++++++++++++++++++++++++++++++++------ 1 files changed, 38 insertions(+), 6 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.62 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.63 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.62 Sun Oct 2 20:04:44 2005 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Sun Oct 2 21:50:05 2005 @@ -319,13 +319,45 @@ /// the loop, resulting in reg-reg copies (if we use the pre-inc value when we /// should use the post-inc value). static bool IVUseShouldUsePostIncValue(Instruction *User, Instruction *IV, - Loop *L, DominatorSet *DS) { + Loop *L, DominatorSet *DS, Pass *P) { // If the user is in the loop, use the preinc value. if (L->contains(User->getParent())) return false; - // Ok, the user is outside of the loop. If it is not dominated by the latch - // block, we have to use the preincremented value. - return DS->dominates(L->getLoopLatch(), User->getParent()); + BasicBlock *LatchBlock = L->getLoopLatch(); + + // Ok, the user is outside of the loop. If it is dominated by the latch + // block, use the post-inc value. + if (DS->dominates(LatchBlock, User->getParent())) + return true; + + // There is one case we have to be careful of: PHI nodes. These little guys + // can live in blocks that do not dominate the latch block, but (since their + // uses occur in the predecessor block, not the block the PHI lives in) should + // still use the post-inc value. Check for this case now. + PHINode *PN = dyn_cast(User); + if (!PN) return false; // not a phi, not dominated by latch block. + + // Look at all of the uses of IV by the PHI node. If any use corresponds to + // a block that is not dominated by the latch block, give up and use the + // preincremented value. + unsigned NumUses = 0; + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + if (PN->getIncomingValue(i) == IV) { + ++NumUses; + if (!DS->dominates(LatchBlock, PN->getIncomingBlock(i))) + return false; + } + + // Okay, all uses of IV by PN are in predecessor blocks that really are + // dominated by the latch block. Split the critical edges and use the + // post-incremented value. + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + if (PN->getIncomingValue(i) == IV) { + SplitCriticalEdge(PN->getIncomingBlock(i), PN->getParent(), P); + if (--NumUses == 0) break; + } + + return true; } @@ -373,12 +405,13 @@ // Okay, we found a user that we cannot reduce. Analyze the instruction // and decide what to do with it. If we are a use inside of the loop, use // the value before incrementation, otherwise use it after incrementation. - if (IVUseShouldUsePostIncValue(User, I, L, DS)) { + if (IVUseShouldUsePostIncValue(User, I, L, DS, this)) { // The value used will be incremented by the stride more than we are // expecting, so subtract this off. SCEVHandle NewStart = SCEV::getMinusSCEV(Start, Stride); IVUsesByStride[Stride].addUser(NewStart, User, I); IVUsesByStride[Stride].Users.back().isUseOfPostIncrementedValue = true; + DEBUG(std::cerr << " USING POSTINC SCEV, START=" << *NewStart<< "\n"); } else { IVUsesByStride[Stride].addUser(Start, User, I); } @@ -481,7 +514,6 @@ BasicBlock *PHIPred = PN->getIncomingBlock(i); if (e != 1 && PHIPred->getTerminator()->getNumSuccessors() > 1 && (PN->getParent() != L->getHeader() || !L->contains(PHIPred))) { - // First step, split the critical edge. SplitCriticalEdge(PHIPred, PN->getParent(), P); From lattner at cs.uiuc.edu Sun Oct 2 22:32:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 22:32:50 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200510030332.WAA23940@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.64 -> 1.65 --- Log message: Fix case of path --- Diffs of the changes: (+1 -1) MRegisterInfo.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.64 llvm/include/llvm/Target/MRegisterInfo.h:1.65 --- llvm/include/llvm/Target/MRegisterInfo.h:1.64 Sun Oct 2 19:21:25 2005 +++ llvm/include/llvm/Target/MRegisterInfo.h Sun Oct 2 22:32:39 2005 @@ -17,7 +17,7 @@ #define LLVM_TARGET_MREGISTERINFO_H #include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/Codegen/ValueTypes.h" +#include "llvm/CodeGen/ValueTypes.h" #include #include From lattner at cs.uiuc.edu Sun Oct 2 23:47:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 2 Oct 2005 23:47:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PHIElimination.cpp Message-ID: <200510030447.XAA24197@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: PHIElimination.cpp updated: 1.37 -> 1.38 --- Log message: Break the body of the loop out into a new method --- Diffs of the changes: (+154 -143) PHIElimination.cpp | 297 +++++++++++++++++++++++++++-------------------------- 1 files changed, 154 insertions(+), 143 deletions(-) Index: llvm/lib/CodeGen/PHIElimination.cpp diff -u llvm/lib/CodeGen/PHIElimination.cpp:1.37 llvm/lib/CodeGen/PHIElimination.cpp:1.38 --- llvm/lib/CodeGen/PHIElimination.cpp:1.37 Tue Aug 23 18:42:17 2005 +++ llvm/lib/CodeGen/PHIElimination.cpp Sun Oct 2 23:47:08 2005 @@ -22,6 +22,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" +#include using namespace llvm; namespace { @@ -46,6 +47,10 @@ /// in predecessor basic blocks. /// bool EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB); + void LowerAtomicPHINode(MachineBasicBlock &MBB, + MachineBasicBlock::iterator AfterPHIsIt, + DenseMap &VUC, + unsigned BBIsSuccOfPreds); }; RegisterPass X("phi-node-elimination", @@ -60,11 +65,7 @@ /// bool PNE::EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB) { if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI) - return false; // Quick exit for normal case... - - LiveVariables *LV = getAnalysisToUpdate(); - const TargetInstrInfo &MII = *MF.getTarget().getInstrInfo(); - const MRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); + return false; // Quick exit for basic blocks without PHIs. // VRegPHIUseCount - Keep track of the number of times each virtual register // is used by PHI nodes in successors of this block. @@ -84,169 +85,179 @@ } // Get an iterator to the first instruction after the last PHI node (this may - // also be the end of the basic block). While we are scanning the PHIs, - // populate the VRegPHIUseCount map. + // also be the end of the basic block). MachineBasicBlock::iterator AfterPHIsIt = MBB.begin(); while (AfterPHIsIt != MBB.end() && AfterPHIsIt->getOpcode() == TargetInstrInfo::PHI) ++AfterPHIsIt; // Skip over all of the PHI nodes... while (MBB.front().getOpcode() == TargetInstrInfo::PHI) { - // Unlink the PHI node from the basic block, but don't delete the PHI yet. - MachineInstr *MPhi = MBB.remove(MBB.begin()); + LowerAtomicPHINode(MBB, AfterPHIsIt, VRegPHIUseCount, BBIsSuccOfPreds); + } + return true; +} - assert(MRegisterInfo::isVirtualRegister(MPhi->getOperand(0).getReg()) && - "PHI node doesn't write virt reg?"); +/// LowerAtomicPHINode - Lower the PHI node at the top of the specified block, +/// under the assuption that it needs to be lowered in a way that supports +/// atomic execution of PHIs. This lowering method is always correct all of the +/// time. +void PNE::LowerAtomicPHINode(MachineBasicBlock &MBB, + MachineBasicBlock::iterator AfterPHIsIt, + DenseMap &VRegPHIUseCount, + unsigned BBIsSuccOfPreds) { + // Unlink the PHI node from the basic block, but don't delete the PHI yet. + MachineInstr *MPhi = MBB.remove(MBB.begin()); + + unsigned DestReg = MPhi->getOperand(0).getReg(); + + // Create a new register for the incoming PHI arguments/ + MachineFunction &MF = *MBB.getParent(); + const TargetRegisterClass *RC = MF.getSSARegMap()->getRegClass(DestReg); + unsigned IncomingReg = MF.getSSARegMap()->createVirtualRegister(RC); + + // Insert a register to register copy in the top of the current block (but + // after any remaining phi nodes) which copies the new incoming register + // into the phi node destination. + // + const MRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); + RegInfo->copyRegToReg(MBB, AfterPHIsIt, DestReg, IncomingReg, RC); - unsigned DestReg = MPhi->getOperand(0).getReg(); + // Update live variable information if there is any... + LiveVariables *LV = getAnalysisToUpdate(); + if (LV) { + MachineInstr *PHICopy = prior(AfterPHIsIt); - // Create a new register for the incoming PHI arguments - const TargetRegisterClass *RC = MF.getSSARegMap()->getRegClass(DestReg); - unsigned IncomingReg = MF.getSSARegMap()->createVirtualRegister(RC); + // Add information to LiveVariables to know that the incoming value is + // killed. Note that because the value is defined in several places (once + // each for each incoming block), the "def" block and instruction fields + // for the VarInfo is not filled in. + // + LV->addVirtualRegisterKilled(IncomingReg, PHICopy); - // Insert a register to register copy in the top of the current block (but - // after any remaining phi nodes) which copies the new incoming register - // into the phi node destination. + // Since we are going to be deleting the PHI node, if it is the last use + // of any registers, or if the value itself is dead, we need to move this + // information over to the new copy we just inserted. // - RegInfo->copyRegToReg(MBB, AfterPHIsIt, DestReg, IncomingReg, RC); + LV->removeVirtualRegistersKilled(MPhi); - // Update live variable information if there is any... - if (LV) { - MachineInstr *PHICopy = prior(AfterPHIsIt); - - // Add information to LiveVariables to know that the incoming value is - // killed. Note that because the value is defined in several places (once - // each for each incoming block), the "def" block and instruction fields - // for the VarInfo is not filled in. - // - LV->addVirtualRegisterKilled(IncomingReg, PHICopy); - - // Since we are going to be deleting the PHI node, if it is the last use - // of any registers, or if the value itself is dead, we need to move this - // information over to the new copy we just inserted. - // - LV->removeVirtualRegistersKilled(MPhi); - - std::pair - RKs = LV->dead_range(MPhi); - if (RKs.first != RKs.second) { - for (LiveVariables::killed_iterator I = RKs.first; I != RKs.second; ++I) - LV->addVirtualRegisterDead(*I, PHICopy); - LV->removeVirtualRegistersDead(MPhi); - } + std::pair + RKs = LV->dead_range(MPhi); + if (RKs.first != RKs.second) { + for (LiveVariables::killed_iterator I = RKs.first; I != RKs.second; ++I) + LV->addVirtualRegisterDead(*I, PHICopy); + LV->removeVirtualRegistersDead(MPhi); } + } - // Adjust the VRegPHIUseCount map to account for the removal of this PHI - // node. - for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2) - VRegPHIUseCount[MPhi->getOperand(i).getReg()] -= BBIsSuccOfPreds; - - // Now loop over all of the incoming arguments, changing them to copy into - // the IncomingReg register in the corresponding predecessor basic block. + // Adjust the VRegPHIUseCount map to account for the removal of this PHI + // node. + for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2) + VRegPHIUseCount[MPhi->getOperand(i).getReg()] -= BBIsSuccOfPreds; + + // Now loop over all of the incoming arguments, changing them to copy into + // the IncomingReg register in the corresponding predecessor basic block. + // + for (int i = MPhi->getNumOperands() - 1; i >= 2; i-=2) { + MachineOperand &opVal = MPhi->getOperand(i-1); + + // Get the MachineBasicBlock equivalent of the BasicBlock that is the + // source path the PHI. + MachineBasicBlock &opBlock = *MPhi->getOperand(i).getMachineBasicBlock(); + + MachineBasicBlock::iterator I = opBlock.getFirstTerminator(); + + // Check to make sure we haven't already emitted the copy for this block. + // This can happen because PHI nodes may have multiple entries for the + // same basic block. It doesn't matter which entry we use though, because + // all incoming values are guaranteed to be the same for a particular bb. + // + // If we emitted a copy for this basic block already, it will be right + // where we want to insert one now. Just check for a definition of the + // register we are interested in! // - for (int i = MPhi->getNumOperands() - 1; i >= 2; i-=2) { - MachineOperand &opVal = MPhi->getOperand(i-1); + bool HaveNotEmitted = true; - // Get the MachineBasicBlock equivalent of the BasicBlock that is the - // source path the PHI. - MachineBasicBlock &opBlock = *MPhi->getOperand(i).getMachineBasicBlock(); - - MachineBasicBlock::iterator I = opBlock.getFirstTerminator(); - - // Check to make sure we haven't already emitted the copy for this block. - // This can happen because PHI nodes may have multiple entries for the - // same basic block. It doesn't matter which entry we use though, because - // all incoming values are guaranteed to be the same for a particular bb. - // - // If we emitted a copy for this basic block already, it will be right - // where we want to insert one now. Just check for a definition of the - // register we are interested in! - // - bool HaveNotEmitted = true; - - if (I != opBlock.begin()) { - MachineBasicBlock::iterator PrevInst = prior(I); - for (unsigned i = 0, e = PrevInst->getNumOperands(); i != e; ++i) { - MachineOperand &MO = PrevInst->getOperand(i); - if (MO.isRegister() && MO.getReg() == IncomingReg) - if (MO.isDef()) { - HaveNotEmitted = false; - break; - } - } + if (I != opBlock.begin()) { + MachineBasicBlock::iterator PrevInst = prior(I); + for (unsigned i = 0, e = PrevInst->getNumOperands(); i != e; ++i) { + MachineOperand &MO = PrevInst->getOperand(i); + if (MO.isRegister() && MO.getReg() == IncomingReg) + if (MO.isDef()) { + HaveNotEmitted = false; + break; + } } + } + + if (HaveNotEmitted) { // If the copy has not already been emitted, do it. + assert(MRegisterInfo::isVirtualRegister(opVal.getReg()) && + "Machine PHI Operands must all be virtual registers!"); + unsigned SrcReg = opVal.getReg(); + RegInfo->copyRegToReg(opBlock, I, IncomingReg, SrcReg, RC); + + // Now update live variable information if we have it. + if (LV) { + // We want to be able to insert a kill of the register if this PHI + // (aka, the copy we just inserted) is the last use of the source + // value. Live variable analysis conservatively handles this by + // saying that the value is live until the end of the block the PHI + // entry lives in. If the value really is dead at the PHI copy, there + // will be no successor blocks which have the value live-in. + // + // Check to see if the copy is the last use, and if so, update the + // live variables information so that it knows the copy source + // instruction kills the incoming value. + // + LiveVariables::VarInfo &InRegVI = LV->getVarInfo(SrcReg); + + // Loop over all of the successors of the basic block, checking to see + // if the value is either live in the block, or if it is killed in the + // block. Also check to see if this register is in use by another PHI + // node which has not yet been eliminated. If so, it will be killed + // at an appropriate point later. + // + bool ValueIsLive = false; + for (MachineBasicBlock::succ_iterator SI = opBlock.succ_begin(), + E = opBlock.succ_end(); SI != E && !ValueIsLive; ++SI) { + MachineBasicBlock *SuccMBB = *SI; + + // Is it alive in this successor? + unsigned SuccIdx = SuccMBB->getNumber(); + if (SuccIdx < InRegVI.AliveBlocks.size() && + InRegVI.AliveBlocks[SuccIdx]) { + ValueIsLive = true; + break; + } - if (HaveNotEmitted) { // If the copy has not already been emitted, do it. - assert(MRegisterInfo::isVirtualRegister(opVal.getReg()) && - "Machine PHI Operands must all be virtual registers!"); - unsigned SrcReg = opVal.getReg(); - RegInfo->copyRegToReg(opBlock, I, IncomingReg, SrcReg, RC); - - // Now update live variable information if we have it. - if (LV) { - // We want to be able to insert a kill of the register if this PHI - // (aka, the copy we just inserted) is the last use of the source - // value. Live variable analysis conservatively handles this by - // saying that the value is live until the end of the block the PHI - // entry lives in. If the value really is dead at the PHI copy, there - // will be no successor blocks which have the value live-in. - // - // Check to see if the copy is the last use, and if so, update the - // live variables information so that it knows the copy source - // instruction kills the incoming value. - // - LiveVariables::VarInfo &InRegVI = LV->getVarInfo(SrcReg); - - // Loop over all of the successors of the basic block, checking to see - // if the value is either live in the block, or if it is killed in the - // block. Also check to see if this register is in use by another PHI - // node which has not yet been eliminated. If so, it will be killed - // at an appropriate point later. - // - bool ValueIsLive = false; - for (MachineBasicBlock::succ_iterator SI = opBlock.succ_begin(), - E = opBlock.succ_end(); SI != E && !ValueIsLive; ++SI) { - MachineBasicBlock *SuccMBB = *SI; - - // Is it alive in this successor? - unsigned SuccIdx = SuccMBB->getNumber(); - if (SuccIdx < InRegVI.AliveBlocks.size() && - InRegVI.AliveBlocks[SuccIdx]) { + // Is it killed in this successor? + for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) + if (InRegVI.Kills[i]->getParent() == SuccMBB) { ValueIsLive = true; break; } - // Is it killed in this successor? - for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) - if (InRegVI.Kills[i]->getParent() == SuccMBB) { - ValueIsLive = true; - break; - } - - // Is it used by any PHI instructions in this block? - if (!ValueIsLive) - ValueIsLive = VRegPHIUseCount[SrcReg] != 0; - } + // Is it used by any PHI instructions in this block? + if (!ValueIsLive) + ValueIsLive = VRegPHIUseCount[SrcReg] != 0; + } - // Okay, if we now know that the value is not live out of the block, - // we can add a kill marker to the copy we inserted saying that it - // kills the incoming value! - // - if (!ValueIsLive) { - MachineBasicBlock::iterator Prev = prior(I); - LV->addVirtualRegisterKilled(SrcReg, Prev); - - // This vreg no longer lives all of the way through opBlock. - unsigned opBlockNum = opBlock.getNumber(); - if (opBlockNum < InRegVI.AliveBlocks.size()) - InRegVI.AliveBlocks[opBlockNum] = false; - } + // Okay, if we now know that the value is not live out of the block, + // we can add a kill marker to the copy we inserted saying that it + // kills the incoming value! + // + if (!ValueIsLive) { + MachineBasicBlock::iterator Prev = prior(I); + LV->addVirtualRegisterKilled(SrcReg, Prev); + + // This vreg no longer lives all of the way through opBlock. + unsigned opBlockNum = opBlock.getNumber(); + if (opBlockNum < InRegVI.AliveBlocks.size()) + InRegVI.AliveBlocks[opBlockNum] = false; } } } - - // Really delete the PHI instruction now! - delete MPhi; } - return true; + + // Really delete the PHI instruction now! + delete MPhi; }