From lattner at cs.uiuc.edu Mon Dec 5 01:04:34 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 5 Dec 2005 01:04:34 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200512050704.BAA07935@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.180 -> 1.181 --- Log message: Add a new llc-beta option for PPC and X86 tonight --- Diffs of the changes: (+4 -2) Makefile.programs | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.180 llvm-test/Makefile.programs:1.181 --- llvm-test/Makefile.programs:1.180 Wed Nov 30 01:14:26 2005 +++ llvm-test/Makefile.programs Mon Dec 5 01:04:22 2005 @@ -187,7 +187,8 @@ endif#DISABLE_DIFFS ifeq ($(ARCH),PowerPC) -LLCBETAOPTION := -sched=simple +LLCBETAOPTION := -enable-gep-isel-opt +#-sched=simple endif ifeq ($(ARCH),Alpha) LLCBETAOPTION := -enable-dag-isel-for-alpha @@ -197,7 +198,8 @@ LLCBETAOPTION := -enable-ia64-dag-isel endif ifeq ($(ARCH),x86) -LLCBETAOPTION := -enable-x86-fastcc +LLCBETAOPTION := -enable-gep-isel-opt +#-enable-x86-fastcc endif # Given a version of the entire program linked together into a single unit of From lattner at cs.uiuc.edu Mon Dec 5 01:10:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 5 Dec 2005 01:10:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200512050710.BAA08012@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.109 -> 1.110 --- Log message: Fix the #1 code quality problem that I have seen on X86 (and it also affects PPC and other targets). In a particular, consider code like this: struct Vector3 { double x, y, z; }; struct Matrix3 { Vector3 a, b, c; }; double dot(Vector3 &a, Vector3 &b) { return a.x * b.x + a.y * b.y + a.z * b.z; } Vector3 mul(Vector3 &a, Matrix3 &b) { Vector3 r; r.x = dot( a, b.a ); r.y = dot( a, b.b ); r.z = dot( a, b.c ); return r; } void transform(Matrix3 &m, Vector3 *x, int n) { for (int i = 0; i < n; i++) x[i] = mul( x[i], m ); } we compile transform to a loop with all of the GEP instructions for indexing into 'm' pulled out of the loop (9 of them). Because isel occurs a bb at a time we are unable to fold the constant index into the loads in the loop, leading to PPC code that looks like this: LBB3_1: ; no_exit.preheader li r2, 0 addi r6, r3, 64 ;; 9 values live across the loop body! addi r7, r3, 56 addi r8, r3, 48 addi r9, r3, 40 addi r10, r3, 32 addi r11, r3, 24 addi r12, r3, 16 addi r30, r3, 8 LBB3_2: ; no_exit lfd f0, 0(r30) lfd f1, 8(r4) fmul f0, f1, f0 lfd f2, 0(r3) ;; no constant indices folded into the loads! lfd f3, 0(r4) lfd f4, 0(r10) lfd f5, 0(r6) lfd f6, 0(r7) lfd f7, 0(r8) lfd f8, 0(r9) lfd f9, 0(r11) lfd f10, 0(r12) lfd f11, 16(r4) fmadd f0, f3, f2, f0 fmul f2, f1, f4 fmadd f0, f11, f10, f0 fmadd f2, f3, f9, f2 fmul f1, f1, f6 stfd f0, 0(r4) fmadd f0, f11, f8, f2 fmadd f1, f3, f7, f1 stfd f0, 8(r4) fmadd f0, f11, f5, f1 addi r29, r4, 24 stfd f0, 16(r4) addi r2, r2, 1 cmpw cr0, r2, r5 or r4, r29, r29 bne cr0, LBB3_2 ; no_exit uh, yuck. With this patch, we now sink the constant offsets into the loop, producing this code: LBB3_1: ; no_exit.preheader li r2, 0 LBB3_2: ; no_exit lfd f0, 8(r3) lfd f1, 8(r4) fmul f0, f1, f0 lfd f2, 0(r3) lfd f3, 0(r4) lfd f4, 32(r3) ;; much nicer. lfd f5, 64(r3) lfd f6, 56(r3) lfd f7, 48(r3) lfd f8, 40(r3) lfd f9, 24(r3) lfd f10, 16(r3) lfd f11, 16(r4) fmadd f0, f3, f2, f0 fmul f2, f1, f4 fmadd f0, f11, f10, f0 fmadd f2, f3, f9, f2 fmul f1, f1, f6 stfd f0, 0(r4) fmadd f0, f11, f8, f2 fmadd f1, f3, f7, f1 stfd f0, 8(r4) fmadd f0, f11, f5, f1 addi r6, r4, 24 stfd f0, 16(r4) addi r2, r2, 1 cmpw cr0, r2, r5 or r4, r6, r6 bne cr0, LBB3_2 ; no_exit This is much nicer as it reduces register pressure in the loop a lot. On X86, this takes the function from having 9 spilled registers to 2. This should help some spec programs on X86 (gzip?) This is currently only enabled with -enable-gep-isel-opt to allow perf testing tonight. --- Diffs of the changes: (+162 -6) SelectionDAGISel.cpp | 168 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 162 insertions(+), 6 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.109 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.110 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.109 Sat Dec 3 12:50:48 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Dec 5 01:10:48 2005 @@ -40,6 +40,10 @@ #include using namespace llvm; +static cl::opt +GEPISelTest("enable-gep-isel-opt", cl::Hidden, + cl::desc("temporary for testing")); + #ifndef NDEBUG static cl::opt ViewDAGs("view-isel-dags", cl::Hidden, @@ -618,7 +622,7 @@ for (GetElementPtrInst::op_iterator OI = I.op_begin()+1, E = I.op_end(); OI != E; ++OI) { Value *Idx = *OI; - if (const StructType *StTy = dyn_cast (Ty)) { + if (const StructType *StTy = dyn_cast(Ty)) { unsigned Field = cast(Idx)->getValue(); if (Field) { // N = N + Offset @@ -1224,21 +1228,173 @@ // updates dom and loop info. } + +/// InsertGEPComputeCode - Insert code into BB to compute Ptr+PtrOffset, +/// casting to the type of GEPI. +static Value *InsertGEPComputeCode(Value *&V, BasicBlock *BB, Instruction *GEPI, + Value *Ptr, Value *PtrOffset) { + if (V) return V; // Already computed. + + BasicBlock::iterator InsertPt; + if (BB == GEPI->getParent()) { + // If insert into the GEP's block, insert right after the GEP. + InsertPt = GEPI; + ++InsertPt; + } else { + // Otherwise, insert at the top of BB, after any PHI nodes + InsertPt = BB->begin(); + while (isa(InsertPt)) ++InsertPt; + } + + // Add the offset, cast it to the right type. + Ptr = BinaryOperator::createAdd(Ptr, PtrOffset, "", InsertPt); + Ptr = new CastInst(Ptr, GEPI->getType(), "", InsertPt); + return V = Ptr; +} + + +/// OptimizeGEPExpression - Since we are doing basic-block-at-a-time instruction +/// selection, we want to be a bit careful about some things. In particular, if +/// we have a GEP instruction that is used in a different block than it is +/// defined, the addressing expression of the GEP cannot be folded into loads or +/// stores that use it. In this case, decompose the GEP and move constant +/// indices into blocks that use it. +static void OptimizeGEPExpression(GetElementPtrInst *GEPI, + const TargetData &TD) { + if (!GEPISelTest) return; + + // If this GEP is only used inside the block it is defined in, there is no + // need to rewrite it. + bool isUsedOutsideDefBB = false; + BasicBlock *DefBB = GEPI->getParent(); + for (Value::use_iterator UI = GEPI->use_begin(), E = GEPI->use_end(); + UI != E; ++UI) { + if (cast(*UI)->getParent() != DefBB) { + isUsedOutsideDefBB = true; + break; + } + } + if (!isUsedOutsideDefBB) return; + + // If this GEP has no non-zero constant indices, there is nothing we can do, + // ignore it. + bool hasConstantIndex = false; + for (GetElementPtrInst::op_iterator OI = GEPI->op_begin()+1, + E = GEPI->op_end(); OI != E; ++OI) { + if (ConstantInt *CI = dyn_cast(*OI)) + if (CI->getRawValue()) { + hasConstantIndex = true; + break; + } + } + if (!hasConstantIndex) return; + + // Otherwise, decompose the GEP instruction into multiplies and adds. Sum the + // constant offset (which we now know is non-zero) and deal with it later. + uint64_t ConstantOffset = 0; + const Type *UIntPtrTy = TD.getIntPtrType(); + Value *Ptr = new CastInst(GEPI->getOperand(0), UIntPtrTy, "", GEPI); + const Type *Ty = GEPI->getOperand(0)->getType(); + + for (GetElementPtrInst::op_iterator OI = GEPI->op_begin()+1, + E = GEPI->op_end(); OI != E; ++OI) { + Value *Idx = *OI; + if (const StructType *StTy = dyn_cast(Ty)) { + unsigned Field = cast(Idx)->getValue(); + if (Field) + ConstantOffset += TD.getStructLayout(StTy)->MemberOffsets[Field]; + Ty = StTy->getElementType(Field); + } else { + Ty = cast(Ty)->getElementType(); + + // Handle constant subscripts. + if (ConstantInt *CI = dyn_cast(Idx)) { + if (CI->getRawValue() == 0) continue; + + if (ConstantSInt *CSI = dyn_cast(CI)) + ConstantOffset += (int64_t)TD.getTypeSize(Ty)*CSI->getValue(); + else + ConstantOffset+=TD.getTypeSize(Ty)*cast(CI)->getValue(); + continue; + } + + // Ptr = Ptr + Idx * ElementSize; + + // Cast Idx to UIntPtrTy if needed. + Idx = new CastInst(Idx, UIntPtrTy, "", GEPI); + + uint64_t ElementSize = TD.getTypeSize(Ty); + // Mask off bits that should not be set. + ElementSize &= ~0ULL >> (64-UIntPtrTy->getPrimitiveSizeInBits()); + Constant *SizeCst = ConstantUInt::get(UIntPtrTy, ElementSize); + + // Multiply by the element size and add to the base. + Idx = BinaryOperator::createMul(Idx, SizeCst, "", GEPI); + Ptr = BinaryOperator::createAdd(Ptr, Idx, "", GEPI); + } + } + + // Make sure that the offset fits in uintptr_t. + ConstantOffset &= ~0ULL >> (64-UIntPtrTy->getPrimitiveSizeInBits()); + Constant *PtrOffset = ConstantUInt::get(UIntPtrTy, ConstantOffset); + + // Okay, we have now emitted all of the variable index parts to the BB that + // the GEP is defined in. Loop over all of the using instructions, inserting + // an "add Ptr, ConstantOffset" into each block that uses it and update the + // instruction to use the newly computed value, making GEPI dead. + std::map InsertedExprs; + while (!GEPI->use_empty()) { + Instruction *User = cast(GEPI->use_back()); + + // Handle PHI's specially, as we need to insert code in the predecessor + // blocks for uses, not in the PHI block. + if (PHINode *PN = dyn_cast(User)) { + for (PHINode::op_iterator OI = PN->op_begin(), E = PN->op_end(); + OI != E; OI += 2) { + if (*OI == GEPI) { + BasicBlock *Pred = cast(OI[1]); + *OI = InsertGEPComputeCode(InsertedExprs[Pred], Pred, GEPI, + Ptr, PtrOffset); + } + } + continue; + } + + // Otherwise, insert the code in the User's block so it can be folded into + // any users in that block. + Value *V = InsertGEPComputeCode(InsertedExprs[User->getParent()], + User->getParent(), GEPI, + Ptr, PtrOffset); + User->replaceUsesOfWith(GEPI, V); + } + + // Finally, the GEP is dead, remove it. + GEPI->eraseFromParent(); +} + bool SelectionDAGISel::runOnFunction(Function &Fn) { MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine()); RegMap = MF.getSSARegMap(); DEBUG(std::cerr << "\n\n\n=== " << Fn.getName() << "\n"); - // First pass, split all critical edges for PHI nodes with incoming values - // that are constants, this way the load of the constant into a vreg will not - // be placed into MBBs that are used some other way. + // First, split all critical edges for PHI nodes with incoming values that are + // constants, this way the load of the constant into a vreg will not be placed + // into MBBs that are used some other way. + // + // In this pass we also look for GEP instructions that are used across basic + // blocks and rewrites them to improve basic-block-at-a-time selection. + // for (Function::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { PHINode *PN; - for (BasicBlock::iterator BBI = BB->begin(); - (PN = dyn_cast(BBI)); ++BBI) + BasicBlock::iterator BBI; + for (BBI = BB->begin(); (PN = dyn_cast(BBI)); ++BBI) for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) if (isa(PN->getIncomingValue(i))) SplitCriticalEdge(PN->getIncomingBlock(i), BB); + + for (BasicBlock::iterator E = BB->end(); BBI != E; ) + if (GetElementPtrInst *GEPI = dyn_cast(BBI++)) + OptimizeGEPExpression(GEPI, TLI.getTargetData()); } FunctionLoweringInfo FuncInfo(TLI, Fn, MF); From alenhar2 at cs.uiuc.edu Mon Dec 5 11:51:26 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 5 Dec 2005 11:51:26 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Message-ID: <200512051751.LAA19346@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelDAGToDAG.cpp updated: 1.11 -> 1.12 --- Log message: fix constant pool loads --- Diffs of the changes: (+1 -1) AlphaISelDAGToDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp diff -u llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.11 llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.12 --- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.11 Wed Nov 30 19:53:10 2005 +++ llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Mon Dec 5 11:51:02 2005 @@ -281,7 +281,7 @@ ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val); SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i64); Tmp = CurDAG->getTargetNode(Alpha::LDAHr, MVT::i64, CPI, getGlobalBaseReg()); - return CurDAG->SelectNodeTo(N, Alpha::LDAr, MVT::i64, CPI, Tmp); + return CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, CPI, Tmp); } break; } From lattner at cs.uiuc.edu Mon Dec 5 12:24:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 5 Dec 2005 12:24:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200512051824.MAA28296@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.70 -> 1.71 --- Log message: getRawValue zero extens for unsigned values, use getsextvalue so that we know that small negative values fit into the immediate field of addressing modes. --- Diffs of the changes: (+3 -3) LoopStrengthReduce.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.70 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.71 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.70 Fri Oct 21 00:45:41 2005 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Dec 5 12:23:57 2005 @@ -560,9 +560,9 @@ // FIXME: Look at the target to decide if &GV is a legal constant immediate. if (SCEVConstant *SC = dyn_cast(V)) { // PPC allows a sign-extended 16-bit immediate field. - if ((int64_t)SC->getValue()->getRawValue() > -(1 << 16) && - (int64_t)SC->getValue()->getRawValue() < (1 << 16)-1) - return true; + int64_t V = SC->getValue()->getSExtValue(); + if (V > -(1 << 16) && V < (1 << 16)-1) + return true; return false; } From alenhar2 at cs.uiuc.edu Mon Dec 5 14:51:05 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 5 Dec 2005 14:51:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp AlphaInstrInfo.td Message-ID: <200512052051.OAA30402@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelDAGToDAG.cpp updated: 1.12 -> 1.13 AlphaInstrInfo.td updated: 1.76 -> 1.77 --- Log message: move this over to the dag --- Diffs of the changes: (+9 -10) AlphaISelDAGToDAG.cpp | 8 -------- AlphaInstrInfo.td | 11 +++++++++-- 2 files changed, 9 insertions(+), 10 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp diff -u llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.12 llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.13 --- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.12 Mon Dec 5 11:51:02 2005 +++ llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Mon Dec 5 14:50:53 2005 @@ -247,14 +247,6 @@ CurDAG->getTargetExternalSymbol(cast(N)->getSymbol(), MVT::i64), getGlobalBaseReg()); - case ISD::CALLSEQ_START: - case ISD::CALLSEQ_END: { - unsigned Amt = cast(N->getOperand(1))->getValue(); - unsigned Opc = N->getOpcode() == ISD::CALLSEQ_START ? - Alpha::ADJUSTSTACKDOWN : Alpha::ADJUSTSTACKUP; - return CurDAG->SelectNodeTo(N, Opc, MVT::Other, - getI64Imm(Amt), Select(N->getOperand(0))); - } case ISD::RET: { SDOperand Chain = Select(N->getOperand(0)); // Token chain. SDOperand InFlag; Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.76 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.77 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.76 Wed Nov 30 11:11:20 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Mon Dec 5 14:50:53 2005 @@ -26,6 +26,11 @@ def Alpha_cvtqs : SDNode<"AlphaISD::CVTQS_", SDTFPUnaryOpUnC, []>; def Alpha_cvttq : SDNode<"AlphaISD::CVTTQ_", SDTFPUnaryOp, []>; +// These are target-independent nodes, but have target-specific formats. +def SDT_AlphaCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i64> ]>; +def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_AlphaCallSeq,[SDNPHasChain]>; +def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_AlphaCallSeq,[SDNPHasChain]>; + //******************** //Paterns for matching @@ -99,8 +104,10 @@ [(set F8RC:$RA, (undef))]>; def WTF : PseudoInstAlpha<(ops variable_ops), "#wtf", []>; -def ADJUSTSTACKUP : PseudoInstAlpha<(ops variable_ops), "ADJUP", []>; -def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops variable_ops), "ADJDOWN", []>; +def ADJUSTSTACKUP : PseudoInstAlpha<(ops s64imm:$amt), "ADJUP", + [(callseq_start imm:$amt)]>; +def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops s64imm:$amt), "ADJDOWN", + [(callseq_end imm:$amt)]>; def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$TARGET:\n", []>; def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n",[]>; def MEMLABEL : PseudoInstAlpha<(ops s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m), From evan.cheng at apple.com Mon Dec 5 17:09:06 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 5 Dec 2005 17:09:06 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200512052309.RAA32142@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.84 -> 1.85 --- Log message: * Infer instruction property hasCtrlDep from pattern if it has one. * Fixed a bug related to hasCtrlDep property use. --- Diffs of the changes: (+50 -31) DAGISelEmitter.cpp | 81 ++++++++++++++++++++++++++++++++--------------------- 1 files changed, 50 insertions(+), 31 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.84 llvm/utils/TableGen/DAGISelEmitter.cpp:1.85 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.84 Sun Dec 4 20:36:37 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Mon Dec 5 17:08:55 2005 @@ -1045,6 +1045,34 @@ } } +/// NodeHasChain - return true if TreePatternNode has the property +/// 'hasChain', meaning it reads a ctrl-flow chain operand and writes +/// a chain result. +static bool NodeHasChain(TreePatternNode *N, DAGISelEmitter &ISE) +{ + if (N->isLeaf()) return false; + Record *Operator = N->getOperator(); + if (!Operator->isSubClassOf("SDNode")) return false; + + const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(Operator); + return NodeInfo.hasProperty(SDNodeInfo::SDNPHasChain); +} + +static bool PatternHasCtrlDep(TreePatternNode *N, DAGISelEmitter &ISE) +{ + if (NodeHasChain(N, ISE)) + return true; + else { + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { + TreePatternNode *Child = N->getChild(i); + if (PatternHasCtrlDep(Child, ISE)) + return true; + } + } + + return false; +} + /// ParseInstructions - Parse all of the instructions, inlining and resolving /// any fragments involved. This populates the Instructions list with fully @@ -1228,7 +1256,7 @@ DAGInstruction &TheInst = II->second; TreePattern *I = TheInst.getPattern(); if (I == 0) continue; // No pattern. - + if (I->getNumTrees() != 1) { std::cerr << "CANNOT HANDLE: " << I->getRecord()->getName() << " yet!"; continue; @@ -1253,6 +1281,12 @@ TreePatternNode *DstPattern = TheInst.getResultPattern(); PatternsToMatch.push_back(std::make_pair(SrcPattern, DstPattern)); + + if (PatternHasCtrlDep(Pattern, *this)) { + Record *Instr = II->first; + CodeGenInstruction &InstInfo = Target.getInstruction(Instr->getName()); + InstInfo.hasCtrlDep = true; + } } } @@ -1602,17 +1636,6 @@ } }; -/// nodeHasChain - return true if TreePatternNode has the property -/// 'hasChain', meaning it reads a ctrl-flow chain operand and writes -/// a chain result. -static bool nodeHasChain(TreePatternNode *N, DAGISelEmitter &ISE) -{ - if (N->isLeaf()) return false; - - const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(N->getOperator()); - return NodeInfo.hasProperty(SDNodeInfo::SDNPHasChain); -} - /// 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. @@ -1650,7 +1673,7 @@ // Emit code to load the child nodes and match their contents recursively. - unsigned OpNo = (unsigned) nodeHasChain(N, *this); + unsigned OpNo = (unsigned) NodeHasChain(N, *this); for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { OS << " SDOperand " << RootName << OpNo <<" = " << RootName << ".getOperand(" << OpNo << ");\n"; @@ -1735,19 +1758,16 @@ std::ostream &OS, bool &HasChain) { if (!N->isLeaf()) { - Record *Op = N->getOperator(); - if (Op->isSubClassOf("Instruction")) { - bool HasCtrlDep = Op->getValueAsBit("hasCtrlDep"); - unsigned OpNo = (unsigned) HasCtrlDep; - for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) - EmitLeadChainForPattern(N->getChild(i), RootName + utostr(OpNo), - OS, HasChain); - - if (!HasChain && HasCtrlDep) { - OS << " SDOperand Chain = Select(" - << RootName << ".getOperand(0));\n"; - HasChain = true; - } + bool hc = NodeHasChain(N, *this); + unsigned OpNo = (unsigned) hc; + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) + EmitLeadChainForPattern(N->getChild(i), RootName + utostr(OpNo), + OS, HasChain); + + if (!HasChain && hc) { + OS << " SDOperand Chain = Select(" + << RootName << ".getOperand(0));\n"; + HasChain = true; } } } @@ -1759,7 +1779,7 @@ std::ostream &OS, bool &HasChain, bool &InFlag) { const CodeGenTarget &T = getTargetInfo(); - unsigned OpNo = (unsigned) nodeHasChain(N, *this); + unsigned OpNo = (unsigned) NodeHasChain(N, *this); for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { TreePatternNode *Child = N->getChild(i); if (!Child->isLeaf()) { @@ -1866,8 +1886,6 @@ Record *Op = N->getOperator(); if (Op->isSubClassOf("Instruction")) { - bool HasCtrlDep = Op->getValueAsBit("hasCtrlDep"); - // Emit all of the operands. std::vector Ops; for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) @@ -1875,6 +1893,7 @@ VariableMap, OS, HasChain, InFlag)); CodeGenInstruction &II = Target.getInstruction(Op->getName()); + bool HasCtrlDep = II.hasCtrlDep; unsigned ResNo = Ctr++; const DAGInstruction &Inst = getInstruction(Op); @@ -1993,7 +2012,7 @@ return false; } - unsigned OpNo = (unsigned) nodeHasChain(Pat, ISE); + unsigned OpNo = (unsigned) NodeHasChain(Pat, ISE); for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i, ++OpNo) if (InsertOneTypeCheck(Pat->getChild(i), Other->getChild(i), ISE, Prefix + utostr(OpNo), PatternNo, OS)) @@ -2062,7 +2081,7 @@ } while (InsertOneTypeCheck(Pat, Pattern.first, *this, "N", PatternNo, OS)); bool HasChain = false; - EmitLeadChainForPattern(Pattern.second, "N", OS, HasChain); + EmitLeadChainForPattern(Pattern.first, "N", OS, HasChain); bool InFlag = false; EmitCopyToRegsForPattern(Pattern.first, "N", OS, HasChain, InFlag); From evan.cheng at apple.com Mon Dec 5 17:09:54 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 5 Dec 2005 17:09:54 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200512052309.RAA32154@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.147 -> 1.148 --- Log message: Remove unnecessary let hasCtrlDep=1 now it can be inferred. --- Diffs of the changes: (+25 -27) X86InstrInfo.td | 52 +++++++++++++++++++++++++--------------------------- 1 files changed, 25 insertions(+), 27 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.147 llvm/lib/Target/X86/X86InstrInfo.td:1.148 --- llvm/lib/Target/X86/X86InstrInfo.td:1.147 Sun Dec 4 20:40:25 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Dec 5 17:09:43 2005 @@ -193,13 +193,13 @@ // // Return instructions. -let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep=1 in +let isTerminator = 1, isReturn = 1, isBarrier = 1 in def RET : I<0xC3, RawFrm, (ops), "ret", [(ret)]>; -let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep=1 in +let isTerminator = 1, isReturn = 1, isBarrier = 1 in def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt", []>; // All branches are RawFrm, Void, Branch, and Terminators -let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in +let isBranch = 1, isTerminator = 1 in class IBr opcode, dag ops, string asm, list pattern> : I; @@ -332,30 +332,28 @@ def IN32ri : Ii8<0xE5, RawFrm, (ops i8imm:$port), "in{l} {$port, %eax|%EAX, $port}", []>, Imp<[],[EAX]>; -let hasCtrlDep=1 in { - def OUT8rr : I<0xEE, RawFrm, (ops), - "out{b} {%al, %dx|%DX, %AL}", - [(writeport AL, DX)]>, Imp<[DX, AL], []>; - def OUT16rr : I<0xEF, RawFrm, (ops), - "out{w} {%ax, %dx|%DX, %AX}", - [(writeport AX, DX)]>, Imp<[DX, AX], []>, OpSize; - def OUT32rr : I<0xEF, RawFrm, (ops), - "out{l} {%eax, %dx|%DX, %EAX}", - [(writeport EAX, DX)]>, Imp<[DX, EAX], []>; - - def OUT8ir : Ii8<0xE6, RawFrm, (ops i16i8imm:$port), - "out{b} {%al, $port|$port, %AL}", - [(writeport AL, (i16 immZExt8:$port))]>, - Imp<[AL], []>; - def OUT16ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port), - "out{w} {%ax, $port|$port, %AX}", - [(writeport AX, (i16 immZExt8:$port))]>, - Imp<[AX], []>, OpSize; - def OUT32ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port), - "out{l} {%eax, $port|$port, %EAX}", - [(writeport EAX, (i16 immZExt8:$port))]>, - Imp<[EAX], []>; -} +def OUT8rr : I<0xEE, RawFrm, (ops), + "out{b} {%al, %dx|%DX, %AL}", + [(writeport AL, DX)]>, Imp<[DX, AL], []>; +def OUT16rr : I<0xEF, RawFrm, (ops), + "out{w} {%ax, %dx|%DX, %AX}", + [(writeport AX, DX)]>, Imp<[DX, AX], []>, OpSize; +def OUT32rr : I<0xEF, RawFrm, (ops), + "out{l} {%eax, %dx|%DX, %EAX}", + [(writeport EAX, DX)]>, Imp<[DX, EAX], []>; + +def OUT8ir : Ii8<0xE6, RawFrm, (ops i16i8imm:$port), + "out{b} {%al, $port|$port, %AL}", + [(writeport AL, (i16 immZExt8:$port))]>, + Imp<[AL], []>; +def OUT16ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port), + "out{w} {%ax, $port|$port, %AX}", + [(writeport AX, (i16 immZExt8:$port))]>, + Imp<[AX], []>, OpSize; +def OUT32ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port), + "out{l} {%eax, $port|$port, %EAX}", + [(writeport EAX, (i16 immZExt8:$port))]>, + Imp<[EAX], []>; //===----------------------------------------------------------------------===// // Move Instructions... From alenhar2 at cs.uiuc.edu Mon Dec 5 17:19:56 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 5 Dec 2005 17:19:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrFormats.td AlphaInstrInfo.td Message-ID: <200512052319.RAA32256@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrFormats.td updated: 1.15 -> 1.16 AlphaInstrInfo.td updated: 1.77 -> 1.78 --- Log message: These never trigger, but whatever --- Diffs of the changes: (+40 -9) AlphaInstrFormats.td | 18 ++++++++++++++++++ AlphaInstrInfo.td | 31 ++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 9 deletions(-) Index: llvm/lib/Target/Alpha/AlphaInstrFormats.td diff -u llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.15 llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.16 --- llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.15 Wed Nov 30 01:19:56 2005 +++ llvm/lib/Target/Alpha/AlphaInstrFormats.td Mon Dec 5 17:19:44 2005 @@ -171,6 +171,24 @@ let Inst{4-0} = Rc; } +class OForm4A opcode, bits<7> fun, string asmstr, list pattern> + : InstAlphaAlt { + let Pattern = pattern; + + bits<5> Rc; + bits<5> Rb; + bits<5> Ra; + bits<7> Function = fun; + + let isTwoAddress = 1; + let Inst{25-21} = Ra; + let Inst{20-16} = Rb; + let Inst{15-13} = 0; + let Inst{12} = 0; + let Inst{11-5} = Function; + let Inst{4-0} = Rc; +} + class OFormL opcode, bits<7> fun, string asmstr, list pattern> : InstAlpha { Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.77 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.78 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.77 Mon Dec 5 14:50:53 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Mon Dec 5 17:19:44 2005 @@ -148,24 +148,37 @@ //Operation Form: //conditional moves, int -def CMOVEQ : OForm4< 0x11, 0x24, "cmoveq $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND = zero def CMOVEQi : OForm4L< 0x11, 0x24, "cmoveq $RCOND,$L,$RDEST">; //CMOVE if RCOND = zero -def CMOVGE : OForm4< 0x11, 0x46, "cmovge $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND >= zero def CMOVGEi : OForm4L< 0x11, 0x46, "cmovge $RCOND,$L,$RDEST">; //CMOVE if RCOND >= zero -def CMOVGT : OForm4< 0x11, 0x66, "cmovgt $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND > zero def CMOVGTi : OForm4L< 0x11, 0x66, "cmovgt $RCOND,$L,$RDEST">; //CMOVE if RCOND > zero -def CMOVLBC : OForm4< 0x11, 0x16, "cmovlbc $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit clear def CMOVLBCi : OForm4L< 0x11, 0x16, "cmovlbc $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit clear -def CMOVLBS : OForm4< 0x11, 0x14, "cmovlbs $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit set def CMOVLBSi : OForm4L< 0x11, 0x14, "cmovlbs $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit set -def CMOVLE : OForm4< 0x11, 0x64, "cmovle $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND <= zero def CMOVLEi : OForm4L< 0x11, 0x64, "cmovle $RCOND,$L,$RDEST">; //CMOVE if RCOND <= zero -def CMOVLT : OForm4< 0x11, 0x44, "cmovlt $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND < zero def CMOVLTi : OForm4L< 0x11, 0x44, "cmovlt $RCOND,$L,$RDEST">; //CMOVE if RCOND < zero -def CMOVNE : OForm4< 0x11, 0x26, "cmovne $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND != zero def CMOVNEi : OForm4L< 0x11, 0x26, "cmovne $RCOND,$L,$RDEST">; //CMOVE if RCOND != zero -//FIXME: fold setcc with select +let OperandList = (ops GPRC:$RDEST, GPRC:$RTRUE, GPRC:$RFALSE, GPRC:$RCOND) in { +def CMOVLBC : OForm4A< 0x11, 0x16, "cmovlbc $RCOND,$RFALSE,$RDEST", + [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))]>; +def CMOVLBS : OForm4A< 0x11, 0x14, "cmovlbs $RCOND,$RFALSE,$RDEST", + [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))]>; +def CMOVEQ : OForm4A< 0x11, 0x24, "cmoveq $RCOND,$RFALSE,$RDEST", + [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; +def CMOVGE : OForm4A< 0x11, 0x46, "cmovge $RCOND,$RFALSE,$RDEST", + [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; +def CMOVGT : OForm4A< 0x11, 0x66, "cmovgt $RCOND,$RFALSE,$RDEST", + [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; +def CMOVLE : OForm4A< 0x11, 0x64, "cmovle $RCOND,$RFALSE,$RDEST", + [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; +def CMOVLT : OForm4A< 0x11, 0x44, "cmovlt $RCOND,$RFALSE,$RDEST", + [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; +def CMOVNE : OForm4A< 0x11, 0x26, "cmovne $RCOND,$RFALSE,$RDEST", + [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; +} + +//FIXME: fold setcc with select for all cases. clearly I need patterns for inverted conditions +// and constants (which require inverted conditions as legalize puts the constant in the +// wrong field for the instruction definition def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2), (CMOVEQ GPRC:$src1, GPRC:$src2, GPRC:$which)>; From alenhar2 at cs.uiuc.edu Mon Dec 5 17:41:57 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 5 Dec 2005 17:41:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrInfo.td Message-ID: <200512052341.RAA32491@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrInfo.td updated: 1.78 -> 1.79 --- Log message: yea, it helps to have your path set right when testing --- Diffs of the changes: (+4 -2) AlphaInstrInfo.td | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.78 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.79 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.78 Mon Dec 5 17:19:44 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Mon Dec 5 17:41:45 2005 @@ -104,10 +104,12 @@ [(set F8RC:$RA, (undef))]>; def WTF : PseudoInstAlpha<(ops variable_ops), "#wtf", []>; -def ADJUSTSTACKUP : PseudoInstAlpha<(ops s64imm:$amt), "ADJUP", +let isLoad = 1, hasCtrlDep = 1 in { +def ADJUSTSTACKUP : PseudoInstAlpha<(ops s64imm:$amt), "; ADJUP $amt", [(callseq_start imm:$amt)]>; -def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops s64imm:$amt), "ADJDOWN", +def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops s64imm:$amt), "; ADJDOWN $amt", [(callseq_end imm:$amt)]>; +} def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$TARGET:\n", []>; def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n",[]>; def MEMLABEL : PseudoInstAlpha<(ops s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m), From alenhar2 at cs.uiuc.edu Mon Dec 5 18:34:05 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 5 Dec 2005 18:34:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrFormats.td AlphaInstrInfo.td Message-ID: <200512060034.SAA00684@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrFormats.td updated: 1.16 -> 1.17 AlphaInstrInfo.td updated: 1.79 -> 1.80 --- Log message: added instructions with inverted immediates --- Diffs of the changes: (+23 -32) AlphaInstrFormats.td | 18 +----------------- AlphaInstrInfo.td | 37 ++++++++++++++++++++++--------------- 2 files changed, 23 insertions(+), 32 deletions(-) Index: llvm/lib/Target/Alpha/AlphaInstrFormats.td diff -u llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.16 llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.17 --- llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.16 Mon Dec 5 17:19:44 2005 +++ llvm/lib/Target/Alpha/AlphaInstrFormats.td Mon Dec 5 18:33:53 2005 @@ -155,23 +155,7 @@ let Inst{4-0} = Rc; } -class OForm4 opcode, bits<7> fun, string asmstr> - : InstAlpha { - bits<5> Rc; - bits<5> Rb; - bits<5> Ra; - bits<7> Function = fun; - - let isTwoAddress = 1; - let Inst{25-21} = Ra; - let Inst{20-16} = Rb; - let Inst{15-13} = 0; - let Inst{12} = 0; - let Inst{11-5} = Function; - let Inst{4-0} = Rc; -} - -class OForm4A opcode, bits<7> fun, string asmstr, list pattern> +class OForm4 opcode, bits<7> fun, string asmstr, list pattern> : InstAlphaAlt { let Pattern = pattern; Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.79 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.80 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.79 Mon Dec 5 17:41:45 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Mon Dec 5 18:33:53 2005 @@ -35,12 +35,19 @@ //******************** //Paterns for matching //******************** - +def invX : SDNodeXFormgetValue()); +}]>; def immUExt8 : PatLeaf<(imm), [{ // immUExt8 predicate - True if the immediate fits in a 8-bit zero extended // field. Used by instructions like 'addi'. return (unsigned long)N->getValue() == (unsigned char)N->getValue(); }]>; +def immUExt8inv : PatLeaf<(imm), [{ + // immUExt8inv predicate - True if the inverted immediate fits in a 8-bit zero extended + // field. Used by instructions like 'ornoti'. + return (unsigned long)~N->getValue() == (unsigned char)~N->getValue(); +}], invX>; def immSExt16 : PatLeaf<(imm), [{ // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended // field. Used by instructions like 'lda'. @@ -160,21 +167,21 @@ def CMOVNEi : OForm4L< 0x11, 0x26, "cmovne $RCOND,$L,$RDEST">; //CMOVE if RCOND != zero let OperandList = (ops GPRC:$RDEST, GPRC:$RTRUE, GPRC:$RFALSE, GPRC:$RCOND) in { -def CMOVLBC : OForm4A< 0x11, 0x16, "cmovlbc $RCOND,$RFALSE,$RDEST", +def CMOVLBC : OForm4< 0x11, 0x16, "cmovlbc $RCOND,$RFALSE,$RDEST", [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVLBS : OForm4A< 0x11, 0x14, "cmovlbs $RCOND,$RFALSE,$RDEST", +def CMOVLBS : OForm4< 0x11, 0x14, "cmovlbs $RCOND,$RFALSE,$RDEST", [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVEQ : OForm4A< 0x11, 0x24, "cmoveq $RCOND,$RFALSE,$RDEST", +def CMOVEQ : OForm4< 0x11, 0x24, "cmoveq $RCOND,$RFALSE,$RDEST", [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVGE : OForm4A< 0x11, 0x46, "cmovge $RCOND,$RFALSE,$RDEST", +def CMOVGE : OForm4< 0x11, 0x46, "cmovge $RCOND,$RFALSE,$RDEST", [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVGT : OForm4A< 0x11, 0x66, "cmovgt $RCOND,$RFALSE,$RDEST", +def CMOVGT : OForm4< 0x11, 0x66, "cmovgt $RCOND,$RFALSE,$RDEST", [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVLE : OForm4A< 0x11, 0x64, "cmovle $RCOND,$RFALSE,$RDEST", +def CMOVLE : OForm4< 0x11, 0x64, "cmovle $RCOND,$RFALSE,$RDEST", [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVLT : OForm4A< 0x11, 0x44, "cmovlt $RCOND,$RFALSE,$RDEST", +def CMOVLT : OForm4< 0x11, 0x44, "cmovlt $RCOND,$RFALSE,$RDEST", [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVNE : OForm4A< 0x11, 0x26, "cmovne $RCOND,$RFALSE,$RDEST", +def CMOVNE : OForm4< 0x11, 0x26, "cmovne $RCOND,$RFALSE,$RDEST", [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; } @@ -199,8 +206,8 @@ [(set GPRC:$RC, (and GPRC:$RA, immUExt8:$L))]>; def BIC : OForm< 0x11, 0x08, "bic $RA,$RB,$RC", [(set GPRC:$RC, (and GPRC:$RA, (not GPRC:$RB)))]>; -def BICi : OFormL<0x11, 0x08, "bic $RA,$L,$RC", []>; -// [(set GPRC:$RC, (and GPRC:$RA, (not immUExt8:$L)))]>; //FIXME? +def BICi : OFormL<0x11, 0x08, "bic $RA,$L,$RC", + [(set GPRC:$RC, (and GPRC:$RA, immUExt8inv:$L))]>; def BIS : OForm< 0x11, 0x20, "bis $RA,$RB,$RC", [(set GPRC:$RC, (or GPRC:$RA, GPRC:$RB))]>; def BISi : OFormL<0x11, 0x20, "bis $RA,$L,$RC", @@ -213,8 +220,8 @@ [(set GPRC:$RC, (cttz GPRC:$RB))]>; def EQV : OForm< 0x11, 0x48, "eqv $RA,$RB,$RC", [(set GPRC:$RC, (xor GPRC:$RA, (not GPRC:$RB)))]>; -def EQVi : OFormL<0x11, 0x48, "eqv $RA,$L,$RC", []>; -// [(set GPRC:$RC, (xor GPRC:$RA, (not immUExt8:$L)))]>; +def EQVi : OFormL<0x11, 0x48, "eqv $RA,$L,$RC", + [(set GPRC:$RC, (xor GPRC:$RA, immUExt8inv:$L))]>; //def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC", []>; //Extract byte low //def EXTBLi : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low //def EXTLH : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high @@ -270,8 +277,8 @@ [(set GPRC:$RC, (mul GPRC:$RA, immUExt8:$L))]>; def ORNOT : OForm< 0x11, 0x28, "ornot $RA,$RB,$RC", [(set GPRC:$RC, (or GPRC:$RA, (not GPRC:$RB)))]>; -def ORNOTi : OFormL<0x11, 0x28, "ornot $RA,$L,$RC", []>; -// [(set GPRC:$RC, (or GPRC:$RA, (not immUExt8:$L)))]>; +def ORNOTi : OFormL<0x11, 0x28, "ornot $RA,$L,$RC", + [(set GPRC:$RC, (or GPRC:$RA, immUExt8inv:$L))]>; def S4ADDL : OForm< 0x10, 0x02, "s4addl $RA,$RB,$RC", [(set GPRC:$RC, (intop (add4 GPRC:$RA, GPRC:$RB)))]>; def S4ADDLi : OFormL<0x10, 0x02, "s4addl $RA,$L,$RC", From lattner at cs.uiuc.edu Mon Dec 5 20:10:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 5 Dec 2005 20:10:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp PPCISelLowering.h PPCInstrInfo.td Message-ID: <200512060210.UAA01486@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.48 -> 1.49 PPCISelLowering.h updated: 1.10 -> 1.11 PPCInstrInfo.td updated: 1.151 -> 1.152 --- Log message: Use new PPC-specific nodes to represent shifts which require the 6-bit amount handling that PPC provides. These are generated by the lowering code and prevents the dag combiner from assuming (rightfully) that the shifts don't only look at 5 bits. This fixes a miscompilation of crafty with the new front-end. --- Diffs of the changes: (+40 -15) PPCISelLowering.cpp | 24 ++++++++++++------------ PPCISelLowering.h | 6 ++++++ PPCInstrInfo.td | 25 ++++++++++++++++++++++--- 3 files changed, 40 insertions(+), 15 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.48 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.49 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.48 Wed Nov 30 14:40:54 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Mon Dec 5 20:10:38 2005 @@ -279,14 +279,14 @@ SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, DAG.getConstant(32, MVT::i32), Amt); - SDOperand Tmp2 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Amt); - SDOperand Tmp3 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Tmp1); + SDOperand Tmp2 = DAG.getNode(PPCISD::SHL, MVT::i32, Hi, Amt); + SDOperand Tmp3 = DAG.getNode(PPCISD::SRL, MVT::i32, Lo, Tmp1); SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, DAG.getConstant(-32U, MVT::i32)); - SDOperand Tmp6 = DAG.getNode(ISD::SHL, MVT::i32, Lo, Tmp5); + SDOperand Tmp6 = DAG.getNode(PPCISD::SHL, MVT::i32, Lo, Tmp5); SDOperand OutHi = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6); - SDOperand OutLo = DAG.getNode(ISD::SHL, MVT::i32, Lo, Amt); + SDOperand OutLo = DAG.getNode(PPCISD::SHL, MVT::i32, Lo, Amt); return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); } case ISD::SRL: { @@ -305,14 +305,14 @@ SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, DAG.getConstant(32, MVT::i32), Amt); - SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt); - SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1); + SDOperand Tmp2 = DAG.getNode(PPCISD::SRL, MVT::i32, Lo, Amt); + SDOperand Tmp3 = DAG.getNode(PPCISD::SHL, MVT::i32, Hi, Tmp1); SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, DAG.getConstant(-32U, MVT::i32)); - SDOperand Tmp6 = DAG.getNode(ISD::SRL, MVT::i32, Hi, Tmp5); + SDOperand Tmp6 = DAG.getNode(PPCISD::SRL, MVT::i32, Hi, Tmp5); SDOperand OutLo = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6); - SDOperand OutHi = DAG.getNode(ISD::SRL, MVT::i32, Hi, Amt); + SDOperand OutHi = DAG.getNode(PPCISD::SRL, MVT::i32, Hi, Amt); return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); } case ISD::SRA: { @@ -330,13 +330,13 @@ SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, DAG.getConstant(32, MVT::i32), Amt); - SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt); - SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1); + SDOperand Tmp2 = DAG.getNode(PPCISD::SRL, MVT::i32, Lo, Amt); + SDOperand Tmp3 = DAG.getNode(PPCISD::SHL, MVT::i32, Hi, Tmp1); SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, DAG.getConstant(-32U, MVT::i32)); - SDOperand Tmp6 = DAG.getNode(ISD::SRA, MVT::i32, Hi, Tmp5); - SDOperand OutHi = DAG.getNode(ISD::SRA, MVT::i32, Hi, Amt); + SDOperand Tmp6 = DAG.getNode(PPCISD::SRA, MVT::i32, Hi, Tmp5); + SDOperand OutHi = DAG.getNode(PPCISD::SRA, MVT::i32, Hi, Amt); SDOperand OutLo = DAG.getSelectCC(Tmp5, DAG.getConstant(0, MVT::i32), Tmp4, Tmp6, ISD::SETLE); return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.10 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.11 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.10 Thu Nov 17 01:30:41 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Mon Dec 5 20:10:38 2005 @@ -49,6 +49,12 @@ /// GlobalBaseReg - On Darwin, this node represents the result of the mflr /// at function entry, used for PIC code. GlobalBaseReg, + + + /// These nodes represent the 32-bit PPC shifts that operate on 6-bit + /// shift amounts. These nodes are generated by the multi-precision shift + /// code. + SRL, SRA, SHL, }; } Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.151 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.152 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.151 Sun Dec 4 20:34:05 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Mon Dec 5 20:10:38 2005 @@ -30,6 +30,15 @@ def PPChi : SDNode<"PPCISD::Hi", SDTIntBinOp, []>; def PPClo : SDNode<"PPCISD::Lo", SDTIntBinOp, []>; +// These nodes represent the 32-bit PPC shifts that operate on 6-bit shift +// amounts. These nodes are generated by the multi-precision shift code. +def SDT_PPCShiftOp : SDTypeProfile<1, 2, [ // PPCshl, PPCsra, PPCsrl + SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32> +]>; +def PPCsrl : SDNode<"PPCISD::SRL" , SDT_PPCShiftOp>; +def PPCsra : SDNode<"PPCISD::SRA" , SDT_PPCShiftOp>; +def PPCshl : SDNode<"PPCISD::SHL" , SDT_PPCShiftOp>; + // These are target-independent nodes, but have target-specific formats. def SDT_PPCCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>; def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeq,[SDNPHasChain]>; @@ -430,19 +439,19 @@ [(set G8RC:$rA, (shl G8RC:$rS, G8RC:$rB))]>, isPPC64; def SLW : XForm_6<31, 24, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "slw $rA, $rS, $rB", IntGeneral, - [(set GPRC:$rA, (shl GPRC:$rS, GPRC:$rB))]>; + [(set GPRC:$rA, (PPCshl GPRC:$rS, GPRC:$rB))]>; def SRD : XForm_6<31, 539, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB), "srd $rA, $rS, $rB", IntRotateD, [(set G8RC:$rA, (srl G8RC:$rS, G8RC:$rB))]>, isPPC64; def SRW : XForm_6<31, 536, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "srw $rA, $rS, $rB", IntGeneral, - [(set GPRC:$rA, (srl GPRC:$rS, GPRC:$rB))]>; + [(set GPRC:$rA, (PPCsrl GPRC:$rS, GPRC:$rB))]>; def SRAD : XForm_6<31, 794, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB), "srad $rA, $rS, $rB", IntRotateD, [(set G8RC:$rA, (sra G8RC:$rS, G8RC:$rB))]>, isPPC64; def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "sraw $rA, $rS, $rB", IntShift, - [(set GPRC:$rA, (sra GPRC:$rS, GPRC:$rB))]>; + [(set GPRC:$rA, (PPCsra 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", LdStGeneral>; @@ -891,6 +900,16 @@ def : Pat<(add GPRC:$in, (PPChi tglobaladdr:$g, 0)), (ADDIS GPRC:$in, tglobaladdr:$g)>; +// Standard shifts. These are represented separately from the real shifts above +// so that we can distinguish between shifts that allow 5-bit and 6-bit shift +// amounts. +def : Pat<(sra GPRC:$rS, GPRC:$rB), + (SRAW GPRC:$rS, GPRC:$rB)>; +def : Pat<(srl GPRC:$rS, GPRC:$rB), + (SRW GPRC:$rS, GPRC:$rB)>; +def : Pat<(shl GPRC:$rS, GPRC:$rB), + (SLW GPRC:$rS, GPRC:$rB)>; + // Same as above, but using a temporary. FIXME: implement temporaries :) /* def : Pattern<(xor GPRC:$in, imm:$imm), From natebegeman at mac.com Tue Dec 6 00:19:07 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 6 Dec 2005 00:19:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp Message-ID: <200512060619.AAA03101@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.222 -> 1.223 SelectionDAG.cpp updated: 1.222 -> 1.223 SelectionDAGISel.cpp updated: 1.110 -> 1.111 --- Log message: Teach the SelectionDAG ISel how to turn ConstantPacked values into constant nodes with vector types. Also teach the asm printer how to print ConstantPacked constant pool entries. This allows us to generate altivec code such as the following, which adds a vector constantto a packed float. LCPI1_0: <4 x float> < float 0.0e+0, float 0.0e+0, float 0.0e+0, float 1.0e+0 > .space 4 .space 4 .space 4 .long 1065353216 ; float 1 .text .align 4 .globl _foo _foo: lis r2, ha16(LCPI1_0) la r2, lo16(LCPI1_0)(r2) li r4, 0 lvx v0, r4, r2 lvx v1, r4, r3 vaddfp v0, v1, v0 stvx v0, r4, r3 blr For the llvm code: void %foo(<4 x float> * %a) { entry: %tmp1 = load <4 x float> * %a; %tmp2 = add <4 x float> %tmp1, < float 0.0, float 0.0, float 0.0, float 1.0 > store <4 x float> %tmp2, <4 x float> *%a ret void } --- Diffs of the changes: (+54 -5) LegalizeDAG.cpp | 26 ++++++++++++++++++++++++++ SelectionDAG.cpp | 3 +-- SelectionDAGISel.cpp | 30 +++++++++++++++++++++++++++--- 3 files changed, 54 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.222 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.223 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.222 Fri Dec 2 00:08:08 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Dec 6 00:18:55 2005 @@ -690,6 +690,32 @@ } break; } + case ISD::ConstantVec: { + // We assume that vector constants are not legal, and will be immediately + // spilled to the constant pool. + // + // FIXME: revisit this when we have some kind of mechanism by which targets + // can decided legality of vector constants, of which there may be very + // many. + // + // Create a ConstantPacked, and put it in the constant pool. + std::vector CV; + MVT::ValueType VT = Node->getValueType(0); + for (unsigned I = 0, E = Node->getNumOperands(); I < E; ++I) { + SDOperand OpN = Node->getOperand(I); + const Type* OpNTy = MVT::getTypeForValueType(OpN.getValueType()); + if (MVT::isFloatingPoint(VT)) + CV.push_back(ConstantFP::get(OpNTy, + cast(OpN)->getValue())); + else + CV.push_back(ConstantUInt::get(OpNTy, + cast(OpN)->getValue())); + } + Constant *CP = ConstantPacked::get(CV); + SDOperand CPIdx = DAG.getConstantPool(CP, Node->getValueType(0)); + Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, DAG.getSrcValue(NULL)); + break; + } case ISD::TokenFactor: if (Node->getNumOperands() == 2) { bool Changed = false; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.222 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.223 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.222 Thu Dec 1 17:14:50 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Dec 6 00:18:55 2005 @@ -501,8 +501,6 @@ return SDOperand(N, 0); } - - SDOperand SelectionDAG::getGlobalAddress(const GlobalValue *GV, MVT::ValueType VT, int offset) { SDNode *&N = GlobalValues[std::make_pair(GV, offset)]; @@ -1837,6 +1835,7 @@ case ISD::Constant: return "Constant"; case ISD::TargetConstant: return "TargetConstant"; case ISD::ConstantFP: return "ConstantFP"; + case ISD::ConstantVec: return "ConstantVec"; case ISD::GlobalAddress: return "GlobalAddress"; case ISD::TargetGlobalAddress: return "TargetGlobalAddress"; case ISD::FrameIndex: return "FrameIndex"; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.110 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.111 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.110 Mon Dec 5 01:10:48 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Dec 6 00:18:55 2005 @@ -282,7 +282,8 @@ SDOperand &N = NodeMap[V]; if (N.Val) return N; - MVT::ValueType VT = TLI.getValueType(V->getType()); + const Type *VTy = V->getType(); + MVT::ValueType VT = TLI.getValueType(VTy); if (Constant *C = const_cast(dyn_cast(V))) if (ConstantExpr *CE = dyn_cast(C)) { visit(CE->getOpcode(), *CE); @@ -296,6 +297,30 @@ return N = DAG.getNode(ISD::UNDEF, VT); } else if (ConstantFP *CFP = dyn_cast(C)) { return N = DAG.getConstantFP(CFP->getValue(), VT); + } else if (const PackedType *PTy = dyn_cast(VTy)) { + unsigned NumElements = PTy->getNumElements(); + MVT::ValueType PVT = TLI.getValueType(PTy->getElementType()); + MVT::ValueType TVT = MVT::getVectorType(PVT, NumElements); + + // Now that we know the number and type of the elements, push a + // Constant or ConstantFP node onto the ops list for each element of + // the packed constant. + std::vector Ops; + for (unsigned i = 0; i < NumElements; ++i) { + const Constant *CEl = C->getOperand(i); + if (MVT::isFloatingPoint(PVT)) + Ops.push_back(DAG.getConstantFP(cast(CEl)->getValue(), + PVT)); + else + Ops.push_back( + DAG.getConstant(cast(CEl)->getRawValue(), + PVT)); + } + // Handle the case where we have a 1-element vector, in which + // case we want to immediately turn it into a scalar constant. + if (Ops.size() == 1) + return N = Ops[0]; + return N = DAG.getNode(ISD::ConstantVec, TVT, Ops); } else { // Canonicalize all constant ints to be unsigned. return N = DAG.getConstant(cast(C)->getRawValue(),VT); @@ -784,8 +809,7 @@ const Type *Ty = I.getType(); SDOperand L; - if (Type::PackedTyID == Ty->getTypeID()) { - const PackedType *PTy = cast(Ty); + if (const PackedType *PTy = dyn_cast(Ty)) { unsigned NumElements = PTy->getNumElements(); MVT::ValueType PVT = TLI.getValueType(PTy->getElementType()); MVT::ValueType TVT = MVT::getVectorType(PVT, NumElements); From natebegeman at mac.com Tue Dec 6 00:19:07 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 6 Dec 2005 00:19:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200512060619.AAA03107@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.29 -> 1.30 --- Log message: Teach the SelectionDAG ISel how to turn ConstantPacked values into constant nodes with vector types. Also teach the asm printer how to print ConstantPacked constant pool entries. This allows us to generate altivec code such as the following, which adds a vector constantto a packed float. LCPI1_0: <4 x float> < float 0.0e+0, float 0.0e+0, float 0.0e+0, float 1.0e+0 > .space 4 .space 4 .space 4 .long 1065353216 ; float 1 .text .align 4 .globl _foo _foo: lis r2, ha16(LCPI1_0) la r2, lo16(LCPI1_0)(r2) li r4, 0 lvx v0, r4, r2 lvx v1, r4, r3 vaddfp v0, v1, v0 stvx v0, r4, r3 blr For the llvm code: void %foo(<4 x float> * %a) { entry: %tmp1 = load <4 x float> * %a; %tmp2 = add <4 x float> %tmp1, < float 0.0, float 0.0, float 0.0, float 1.0 > store <4 x float> %tmp2, <4 x float> *%a ret void } --- Diffs of the changes: (+8 -0) AsmPrinter.cpp | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.29 llvm/lib/CodeGen/AsmPrinter.cpp:1.30 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.29 Mon Nov 21 02:25:09 2005 +++ llvm/lib/CodeGen/AsmPrinter.cpp Tue Dec 6 00:18:55 2005 @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/DerivedTypes.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/Constants.h" #include "llvm/Module.h" @@ -326,6 +327,13 @@ } return; } + } else if (const ConstantPacked *CP = dyn_cast(CV)) { + const PackedType *PTy = CP->getType(); + + for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I) + EmitGlobalConstant(CP->getOperand(I)); + + return; } const Type *type = CV->getType(); From natebegeman at mac.com Tue Dec 6 00:19:07 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 6 Dec 2005 00:19:07 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200512060619.AAA03105@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.80 -> 1.81 --- Log message: Teach the SelectionDAG ISel how to turn ConstantPacked values into constant nodes with vector types. Also teach the asm printer how to print ConstantPacked constant pool entries. This allows us to generate altivec code such as the following, which adds a vector constantto a packed float. LCPI1_0: <4 x float> < float 0.0e+0, float 0.0e+0, float 0.0e+0, float 1.0e+0 > .space 4 .space 4 .space 4 .long 1065353216 ; float 1 .text .align 4 .globl _foo _foo: lis r2, ha16(LCPI1_0) la r2, lo16(LCPI1_0)(r2) li r4, 0 lvx v0, r4, r2 lvx v1, r4, r3 vaddfp v0, v1, v0 stvx v0, r4, r3 blr For the llvm code: void %foo(<4 x float> * %a) { entry: %tmp1 = load <4 x float> * %a; %tmp2 = add <4 x float> %tmp1, < float 0.0, float 0.0, float 0.0, float 1.0 > store <4 x float> %tmp2, <4 x float> *%a ret void } --- Diffs of the changes: (+4 -0) SelectionDAGNodes.h | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.80 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.81 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.80 Tue Nov 29 20:04:11 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Tue Dec 6 00:18:55 2005 @@ -67,6 +67,10 @@ GlobalAddress, FrameIndex, ConstantPool, BasicBlock, ExternalSymbol, VALUETYPE, CONDCODE, Register, + // ConstantVec works like Constant or ConstantFP, except that it is not a + // leaf node. All operands are either Constant or ConstantFP nodes. + ConstantVec, + // TargetConstant - Like Constant, but the DAG does not do any folding or // simplification of the constant. This is used by the DAG->DAG selector. TargetConstant, From lattner at cs.uiuc.edu Tue Dec 6 01:05:39 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 6 Dec 2005 01:05:39 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/ADT/PostOrderIterator.h Message-ID: <200512060705.BAA03437@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/ADT: PostOrderIterator.h updated: 1.18 -> 1.19 --- Log message: Implement external storage for post-order iteration, implementing PR267: http://llvm.cs.uiuc.edu/PR267 Patch by Saem Ghani, thanks! --- Diffs of the changes: (+84 -10) PostOrderIterator.h | 94 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 84 insertions(+), 10 deletions(-) Index: llvm/include/llvm/ADT/PostOrderIterator.h diff -u llvm/include/llvm/ADT/PostOrderIterator.h:1.18 llvm/include/llvm/ADT/PostOrderIterator.h:1.19 --- llvm/include/llvm/ADT/PostOrderIterator.h:1.18 Thu Apr 21 22:25:01 2005 +++ llvm/include/llvm/ADT/PostOrderIterator.h Tue Dec 6 01:05:27 2005 @@ -23,8 +23,26 @@ namespace llvm { -template > -class po_iterator : public forward_iterator { +template // Non-external set +class po_iterator_storage { +public: + SetType Visited; +}; + +template +class po_iterator_storage { +public: + po_iterator_storage(SetType &VSet) : Visited(VSet) {} + po_iterator_storage(const po_iterator_storage &S) : Visited(S.Visited) {} + SetType &Visited; +}; + +template::NodeType*>, + bool ExtStorage = false, + class GT = GraphTraits > +class po_iterator : public forward_iterator, + public po_iterator_storage { typedef forward_iterator super; typedef typename GT::NodeType NodeType; typedef typename GT::ChildIteratorType ChildItTy; @@ -37,27 +55,45 @@ void traverseChild() { while (VisitStack.top().second != GT::child_end(VisitStack.top().first)) { NodeType *BB = *VisitStack.top().second++; - if (!Visited.count(BB)) { // If the block is not visited... - Visited.insert(BB); + if (!this->Visited.count(BB)) { // If the block is not visited... + this->Visited.insert(BB); VisitStack.push(std::make_pair(BB, GT::child_begin(BB))); } } } inline po_iterator(NodeType *BB) { - Visited.insert(BB); + this->Visited.insert(BB); VisitStack.push(std::make_pair(BB, GT::child_begin(BB))); traverseChild(); } - inline po_iterator() { /* End is when stack is empty */ } + inline po_iterator() {} // End is when stack is empty. + + inline po_iterator(NodeType *BB, SetType &S) : + po_iterator_storage(&S) { + if(!S.count(BB)) { + this->Visited.insert(BB); + VisitStack.push(std::make_pair(BB, GT::child_begin(BB))); + traverseChild(); + } + } + + inline po_iterator(SetType &S) : + po_iterator_storage(&S) { + } // End is when stack is empty. public: typedef typename super::pointer pointer; - typedef po_iterator _Self; + typedef po_iterator _Self; // Provide static "constructors"... static inline _Self begin(GraphT G) { return _Self(GT::getEntryNode(G)); } static inline _Self end (GraphT G) { return _Self(); } + static inline _Self begin(GraphT G, SetType &S) { + return _Self(GT::getEntryNode(G), S); + } + static inline _Self end (GraphT G, SetType &S) { return _Self(S); } + inline bool operator==(const _Self& x) const { return VisitStack == x.VisitStack; } @@ -92,10 +128,30 @@ template po_iterator po_end (T G) { return po_iterator::end(G); } +// Provide global definitions of external postorder iterators... +template::NodeType*> > +struct po_ext_iterator : public po_iterator { + po_ext_iterator(const po_iterator &V) : + po_iterator(V) {} +}; + +template +po_ext_iterator po_ext_begin(T G, SetType &S) { + return po_ext_iterator::begin(G, S); +} + +template +po_ext_iterator po_ext_end(T G, SetType &S) { + return po_ext_iterator::end(G, S); +} + // Provide global definitions of inverse post order iterators... -template -struct ipo_iterator : public po_iterator > { - ipo_iterator(const po_iterator > &V) :po_iterator >(V){} +template ::NoddeType*>, + bool External = false> +struct ipo_iterator : public po_iterator, SetType, External > { + ipo_iterator(const po_iterator, SetType, External> &V) : + po_iterator, SetType, External> (V) {} }; template @@ -108,6 +164,24 @@ return ipo_iterator::end(G); } +//Provide global definitions of external inverse postorder iterators... +template ::NodeType*> > +struct ipo_ext_iterator : public ipo_iterator { + ipo_ext_iterator(const ipo_iterator &V) : + ipo_iterator(&V) {} + ipo_ext_iterator(const po_iterator, SetType, true> &V) : + ipo_iterator(&V) {} +}; + +template +ipo_ext_iterator ipo_ext_begin(T G, SetType &S) { + return ipo_ext_iterator::begin(G, S); +} + +template +ipo_ext_iterator ipo_ext_end(T G, SetType &S) { + return ipo_ext_iterator::end(G, S); +} //===--------------------------------------------------------------------===// // Reverse Post Order CFG iterator code From lattner at cs.uiuc.edu Tue Dec 6 11:30:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 6 Dec 2005 11:30:06 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Linker/2005-12-06-AppendingZeroLengthArrays.ll Message-ID: <200512061730.LAA03310@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Linker: 2005-12-06-AppendingZeroLengthArrays.ll added (r1.1) --- Log message: new testcase for PR662: http://llvm.cs.uiuc.edu/PR662 --- Diffs of the changes: (+8 -0) 2005-12-06-AppendingZeroLengthArrays.ll | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/test/Regression/Linker/2005-12-06-AppendingZeroLengthArrays.ll diff -c /dev/null llvm/test/Regression/Linker/2005-12-06-AppendingZeroLengthArrays.ll:1.1 *** /dev/null Tue Dec 6 11:30:05 2005 --- llvm/test/Regression/Linker/2005-12-06-AppendingZeroLengthArrays.ll Tue Dec 6 11:29:54 2005 *************** *** 0 **** --- 1,8 ---- + ; RUN: echo "%G = appending global [0 x int] zeroinitializer" | llvm-as > %t.out2.bc + ; RUN: llvm-as < %s > %t.out1.bc + ; RUN: llvm-link %t.out[12].bc | llvm-dis | grep '%G =' + + ; When linked, the globals should be merged, and the result should still + ; be named '%G'. + + %G = appending global [1 x int] zeroinitializer From lattner at cs.uiuc.edu Tue Dec 6 11:31:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 6 Dec 2005 11:31:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/Linker/LinkModules.cpp Message-ID: <200512061731.LAA03367@zion.cs.uiuc.edu> Changes in directory llvm/lib/Linker: LinkModules.cpp updated: 1.107 -> 1.108 --- Log message: Fix test/Regression/Linker/2005-12-06-AppendingZeroLengthArrays.ll and PR662: http://llvm.cs.uiuc.edu/PR662 . Thanks to Markus for providing me with a ton of files to reproduce the problem! --- Diffs of the changes: (+2 -0) LinkModules.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Linker/LinkModules.cpp diff -u llvm/lib/Linker/LinkModules.cpp:1.107 llvm/lib/Linker/LinkModules.cpp:1.108 --- llvm/lib/Linker/LinkModules.cpp:1.107 Thu Jul 7 18:21:43 2005 +++ llvm/lib/Linker/LinkModules.cpp Tue Dec 6 11:30:58 2005 @@ -748,6 +748,8 @@ unsigned NewSize = T1->getNumElements() + T2->getNumElements(); ArrayType *NewType = ArrayType::get(T1->getElementType(), NewSize); + G1->setName(""); // Clear G1's name in case of a conflict! + // Create the new global variable... GlobalVariable *NG = new GlobalVariable(NewType, G1->isConstant(), G1->getLinkage(), From kowshik at cs.uiuc.edu Tue Dec 6 12:01:40 2005 From: kowshik at cs.uiuc.edu (Sumant Kowshik) Date: Tue, 6 Dec 2005 12:01:40 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSNode.h Message-ID: <200512061801.MAA21684@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSNode.h updated: 1.54 -> 1.55 --- Log message: Handling of zero length last fields in struct used for growing it arbitrarily --- Diffs of the changes: (+2 -1) DSNode.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Analysis/DataStructure/DSNode.h diff -u llvm/include/llvm/Analysis/DataStructure/DSNode.h:1.54 llvm/include/llvm/Analysis/DataStructure/DSNode.h:1.55 --- llvm/include/llvm/Analysis/DataStructure/DSNode.h:1.54 Thu Apr 21 15:18:05 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSNode.h Tue Dec 6 12:01:20 2005 @@ -424,12 +424,13 @@ // Disabling this assertion because it is failing on a "magic" struct // in named (from bind). The fourth field is an array of length 0, // presumably used to create struct instances of different sizes. - assert((!N || + /* assert((!N || N->isNodeCompletelyFolded() || (N->Size == 0 && Offset == 0) || (int(Offset) >= 0 && Offset < N->Size) || (int(Offset) < 0 && -int(Offset) < int(N->Size)) || N->isForwarding()) && "Node handle offset out of range!"); + */ if (N == 0 || !N->isForwarding()) return N; From kowshik at cs.uiuc.edu Tue Dec 6 12:04:45 2005 From: kowshik at cs.uiuc.edu (Sumant Kowshik) Date: Tue, 6 Dec 2005 12:04:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Local.cpp Message-ID: <200512061804.MAA21827@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Local.cpp updated: 1.134 -> 1.135 --- Log message: Collapsing node if variable length struct with final field of length zero --- Diffs of the changes: (+18 -1) Local.cpp | 19 ++++++++++++++++++- 1 files changed, 18 insertions(+), 1 deletion(-) Index: llvm/lib/Analysis/DataStructure/Local.cpp diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.134 llvm/lib/Analysis/DataStructure/Local.cpp:1.135 --- llvm/lib/Analysis/DataStructure/Local.cpp:1.134 Sat Jun 18 13:34:51 2005 +++ llvm/lib/Analysis/DataStructure/Local.cpp Tue Dec 6 12:04:30 2005 @@ -434,7 +434,24 @@ // Add in the offset calculated... Value.setOffset(Value.getOffset()+Offset); - // Value is now the pointer we want to GEP to be... + // Check the offset + DSNode *N = Value.getNode(); + if (N && + !N->isNodeCompletelyFolded() && + (N->getSize() != 0 || Offset != 0) && + !N->isForwarding()) { + if ((Offset >= N->getSize()) || int(Offset) < 0) { + // Accessing offsets out of node size range + // This is seen in the "magic" struct in named (from bind), where the + // fourth field is an array of length 0, presumably used to create struct + // instances of different sizes + + // Collapse the node since its size is now variable + N->foldNodeCompletely(); + } + } + + // Value is now the pointer we want to GEP to be... setDestTo(GEP, Value); } From kowshik at cs.uiuc.edu Tue Dec 6 12:07:03 2005 From: kowshik at cs.uiuc.edu (Sumant Kowshik) Date: Tue, 6 Dec 2005 12:07:03 -0600 Subject: [llvm-commits] CVS: llvm-poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp Message-ID: <200512061807.MAA21850@apoc.cs.uiuc.edu> Changes in directory llvm-poolalloc/lib/PoolAllocate: TransformFunctionBody.cpp updated: 1.46 -> 1.47 --- Log message: Removing unnecesary code mapping global nodes --- Diffs of the changes: (+12 -8) TransformFunctionBody.cpp | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-) Index: llvm-poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp diff -u llvm-poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.46 llvm-poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.47 --- llvm-poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.46 Wed May 18 14:56:28 2005 +++ llvm-poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp Tue Dec 6 12:06:43 2005 @@ -514,14 +514,18 @@ DSGraph::computeNodeMapping(CalleeGraph->getReturnNodeFor(*CF), getDSNodeHFor(TheCall), NodeMapping, false); - // Map the nodes that are pointed to by globals. - DSScalarMap &CalleeSM = CalleeGraph->getScalarMap(); - for (DSScalarMap::global_iterator GI = G.getScalarMap().global_begin(), - E = G.getScalarMap().global_end(); GI != E; ++GI) - if (CalleeSM.count(*GI)) - DSGraph::computeNodeMapping(CalleeGraph->getNodeForValue(*GI), - getDSNodeHFor(*GI), - NodeMapping, false); + // This code seems redundant (and crashes occasionally) + // There is no reason to map globals here, since they are not passed as + // arguments + + // Map the nodes that are pointed to by globals. + // DSScalarMap &CalleeSM = CalleeGraph->getScalarMap(); + // for (DSScalarMap::global_iterator GI = G.getScalarMap().global_begin(), + // E = G.getScalarMap().global_end(); GI != E; ++GI) + // if (CalleeSM.count(*GI)) + // DSGraph::computeNodeMapping(CalleeGraph->getNodeForValue(*GI), + // getDSNodeHFor(*GI), + // NodeMapping, false); // Okay, now that we have established our mapping, we can figure out which // pool descriptors to pass in... From kowshik at cs.uiuc.edu Tue Dec 6 12:16:23 2005 From: kowshik at cs.uiuc.edu (Sumant Kowshik) Date: Tue, 6 Dec 2005 12:16:23 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSNode.h Message-ID: <200512061816.MAA21931@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSNode.h updated: 1.55 -> 1.56 --- Log message: Added comment for removing assert --- Diffs of the changes: (+3 -0) DSNode.h | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/include/llvm/Analysis/DataStructure/DSNode.h diff -u llvm/include/llvm/Analysis/DataStructure/DSNode.h:1.55 llvm/include/llvm/Analysis/DataStructure/DSNode.h:1.56 --- llvm/include/llvm/Analysis/DataStructure/DSNode.h:1.55 Tue Dec 6 12:01:20 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSNode.h Tue Dec 6 12:16:08 2005 @@ -424,6 +424,9 @@ // Disabling this assertion because it is failing on a "magic" struct // in named (from bind). The fourth field is an array of length 0, // presumably used to create struct instances of different sizes. + // In a variable length struct, Offset could exceed Size when getNode() + // is called before such a node is folded. In this case, the DS Analysis now + // correctly folds this node after calling getNode. /* assert((!N || N->isNodeCompletelyFolded() || (N->Size == 0 && Offset == 0) || From alenhar2 at cs.uiuc.edu Tue Dec 6 14:40:53 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Tue, 6 Dec 2005 14:40:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrFormats.td Message-ID: <200512062040.OAA22122@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrFormats.td updated: 1.17 -> 1.18 --- Log message: OK, this does wonders for broken stuff --- Diffs of the changes: (+1 -0) AlphaInstrFormats.td | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/Alpha/AlphaInstrFormats.td diff -u llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.17 llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.18 --- llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.17 Mon Dec 5 18:33:53 2005 +++ llvm/lib/Target/Alpha/AlphaInstrFormats.td Tue Dec 6 14:40:34 2005 @@ -102,6 +102,7 @@ let Inst{25-21} = Ra; let Inst{20-0} = disp; } +let isBranch = 1, isTerminator = 1 in class BFormD opcode, string asmstr> : InstAlpha { bits<5> Ra = 31; From alenhar2 at cs.uiuc.edu Tue Dec 6 14:43:46 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Tue, 6 Dec 2005 14:43:46 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Message-ID: <200512062043.OAA22144@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelDAGToDAG.cpp updated: 1.13 -> 1.14 --- Log message: more decent branches for FP. I might have to make some intermediate nodes to actually be able to use the DAG for FPcmp --- Diffs of the changes: (+33 -2) AlphaISelDAGToDAG.cpp | 35 +++++++++++++++++++++++++++++++++-- 1 files changed, 33 insertions(+), 2 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp diff -u llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.13 llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.14 --- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.13 Mon Dec 5 14:50:53 2005 +++ llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Tue Dec 6 14:43:30 2005 @@ -155,6 +155,38 @@ return SDOperand(Result.Val, Op.ResNo); } case ISD::BRCOND: { + if (N->getOperand(1).getOpcode() == ISD::SETCC && + MVT::isFloatingPoint(N->getOperand(1).getOperand(0).getValueType())) { + SDOperand Chain = Select(N->getOperand(0)); + SDOperand CC1 = Select(N->getOperand(1).getOperand(0)); + SDOperand CC2 = Select(N->getOperand(1).getOperand(1)); + ISD::CondCode cCode= cast(N->getOperand(1).getOperand(2))->get(); + + bool rev = false; + bool isNE = false; + unsigned Opc = Alpha::WTF; + switch(cCode) { + default: N->dump(); assert(0 && "Unknown FP comparison!"); + case ISD::SETEQ: Opc = Alpha::CMPTEQ; break; + case ISD::SETLT: Opc = Alpha::CMPTLT; break; + case ISD::SETLE: Opc = Alpha::CMPTLE; break; + case ISD::SETGT: Opc = Alpha::CMPTLT; rev = true; break; + case ISD::SETGE: Opc = Alpha::CMPTLE; rev = true; break; + case ISD::SETNE: Opc = Alpha::CMPTEQ; isNE = true; break; + }; + SDOperand cmp = CurDAG->getTargetNode(Opc, MVT::f64, + rev?CC2:CC1, + rev?CC1:CC2); + + MachineBasicBlock *Dest = + cast(N->getOperand(2))->getBasicBlock(); + if(isNE) + return CurDAG->SelectNodeTo(N, Alpha::FBEQ, MVT::Other, cmp, + CurDAG->getBasicBlock(Dest), Chain); + else + return CurDAG->SelectNodeTo(N, Alpha::FBNE, MVT::Other, cmp, + CurDAG->getBasicBlock(Dest), Chain); + } SDOperand Chain = Select(N->getOperand(0)); SDOperand CC = Select(N->getOperand(1)); MachineBasicBlock *Dest = @@ -220,10 +252,9 @@ Address, Chain); } - case ISD::BR: + case ISD::BR: return CurDAG->SelectNodeTo(N, Alpha::BR_DAG, MVT::Other, N->getOperand(1), Select(N->getOperand(0))); - case ISD::FrameIndex: { int FI = cast(N)->getIndex(); return CurDAG->SelectNodeTo(N, Alpha::LDA, MVT::i64, From alenhar2 at cs.uiuc.edu Tue Dec 6 14:51:46 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Tue, 6 Dec 2005 14:51:46 -0600 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/Miscompilation.cpp Message-ID: <200512062051.OAA22169@apoc.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: Miscompilation.cpp updated: 1.72 -> 1.73 --- Log message: This solves the problem of the CBE renaming symbols that start with . but the assembly side still trying to reference them by their old names. Should be safe untill we hit a language front end that lets you specify such a name. --- Diffs of the changes: (+2 -0) Miscompilation.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/tools/bugpoint/Miscompilation.cpp diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.72 llvm/tools/bugpoint/Miscompilation.cpp:1.73 --- llvm/tools/bugpoint/Miscompilation.cpp:1.72 Sat Oct 22 23:37:20 2005 +++ llvm/tools/bugpoint/Miscompilation.cpp Tue Dec 6 14:51:30 2005 @@ -232,6 +232,8 @@ // mangler is used by the two code generators), but having symbols with the // same name causes warnings to be emitted by the code generator. Mangler Mang(*M); + // Agree with the CBE on symbol naming + Mang.markCharUnacceptable('.'); for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) I->setName(Mang.getValueName(I)); for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) From lattner at cs.uiuc.edu Tue Dec 6 14:56:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 6 Dec 2005 14:56:30 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200512062056.OAA05653@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.138 -> 1.139 --- Log message: Silence another annoying GCC warning --- Diffs of the changes: (+1 -1) PPCISelDAGToDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.138 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.139 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.138 Sun Dec 4 13:04:38 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Tue Dec 6 14:56:18 2005 @@ -720,7 +720,7 @@ // Force the ccreg into CR7. SDOperand CR7Reg = CurDAG->getRegister(PPC::CR7, MVT::i32); - SDOperand InFlag; // Null incoming flag value. + SDOperand InFlag(0, 0); // Null incoming flag value. CCReg = CurDAG->getCopyToReg(CurDAG->getEntryNode(), CR7Reg, CCReg, InFlag).getValue(1); From alenhar2 at cs.uiuc.edu Tue Dec 6 17:28:02 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Tue, 6 Dec 2005 17:28:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp AlphaInstrInfo.td Message-ID: <200512062328.RAA23899@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelDAGToDAG.cpp updated: 1.14 -> 1.15 AlphaInstrInfo.td updated: 1.80 -> 1.81 --- Log message: fix divide and remainder --- Diffs of the changes: (+14 -13) AlphaISelDAGToDAG.cpp | 24 +++++++++++------------- AlphaInstrInfo.td | 3 +++ 2 files changed, 14 insertions(+), 13 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp diff -u llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.14 llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.15 --- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.14 Tue Dec 6 14:43:30 2005 +++ llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Tue Dec 6 17:27:39 2005 @@ -339,19 +339,17 @@ } SDOperand Tmp1 = Select(N->getOperand(0)), Tmp2 = Select(N->getOperand(1)), - Addr = CurDAG->getExternalSymbol(opstr, AlphaLowering.getPointerTy()); - SDOperand Tmp3 = Select(Addr); - SDOperand Chain = CurDAG->getCopyToReg(CurDAG->getRoot(), Alpha::R24, - Tmp1, SDOperand()); - Chain = CurDAG->getCopyToReg(CurDAG->getRoot(), Alpha::R25, - Tmp2, Chain.getValue(1)); - Chain = CurDAG->getCopyToReg(CurDAG->getRoot(), Alpha::R27, - Tmp3, Chain.getValue(1)); - Chain = CurDAG->getTargetNode(Alpha::JSRs, MVT::i64, MVT::Flag, - CurDAG->getRegister(Alpha::R27, MVT::i64), - getI64Imm(0)); - return CurDAG->getCopyFromReg(Chain.getValue(1), Alpha::R27, MVT::i64, - Chain.getValue(1)); + Addr = Select(CurDAG->getExternalSymbol(opstr, + AlphaLowering.getPointerTy())); + SDOperand Chain; + Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), Alpha::R24, Tmp1, + SDOperand(0,0)); + Chain = CurDAG->getCopyToReg(Chain, Alpha::R25, Tmp2, Chain.getValue(1)); + Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Addr, Chain.getValue(1)); + Chain = CurDAG->getTargetNode(Alpha::JSRsDAG, MVT::Other, MVT::Flag, + Chain, Chain.getValue(1)); + return CurDAG->getCopyFromReg(Chain, Alpha::R27, MVT::i64, + Chain.getValue(1)); } break; Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.80 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.81 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.80 Mon Dec 5 18:33:53 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Tue Dec 6 17:27:39 2005 @@ -429,6 +429,9 @@ let isCall = 1, Defs = [R24, R25, R27, R28], Uses = [R24, R25] in def JSRs : MbrForm< 0x1A, 0x01, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr $RD,($RS),$DISP">; //Jump to div or rem +let isCall = 1, Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in + def JSRsDAG : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0">; //Jump to div or rem + def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP">; //Jump to subroutine return def BR : BForm<0x30, "br $RA,$DISP">; //Branch From lattner at cs.uiuc.edu Tue Dec 6 23:41:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 6 Dec 2005 23:41:55 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/ADT/PostOrderIterator.h Message-ID: <200512070541.XAA01205@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/ADT: PostOrderIterator.h updated: 1.19 -> 1.20 --- Log message: Remove a now-dead map, patch by Saem Ghani, thanks! --- Diffs of the changes: (+1 -2) PostOrderIterator.h | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/include/llvm/ADT/PostOrderIterator.h diff -u llvm/include/llvm/ADT/PostOrderIterator.h:1.19 llvm/include/llvm/ADT/PostOrderIterator.h:1.20 --- llvm/include/llvm/ADT/PostOrderIterator.h:1.19 Tue Dec 6 01:05:27 2005 +++ llvm/include/llvm/ADT/PostOrderIterator.h Tue Dec 6 23:41:44 2005 @@ -46,8 +46,7 @@ typedef forward_iterator super; typedef typename GT::NodeType NodeType; typedef typename GT::ChildIteratorType ChildItTy; - - std::set Visited; // All of the blocks visited so far... + // VisitStack - Used to maintain the ordering. Top = current block // First element is basic block pointer, second is the 'next child' to visit std::stack > VisitStack; From lattner at cs.uiuc.edu Wed Dec 7 01:11:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Dec 2005 01:11:15 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200512070711.BAA03974@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.62 -> 1.63 --- Log message: Teach the dag combiner to turn a truncate/sign_extend pair into a sextinreg when the types match up. This allows the X86 backend to compile: sbyte %toggle_value(sbyte* %tmp.1) { %tmp.2 = load sbyte* %tmp.1 ret sbyte %tmp.2 } to this: _toggle_value: mov %EAX, DWORD PTR [%ESP + 4] movsx %EAX, BYTE PTR [%EAX] ret instead of this: _toggle_value: mov %EAX, DWORD PTR [%ESP + 4] movsx %EAX, BYTE PTR [%EAX] movsx %EAX, %AL ret noticed in Shootout/objinst. -Chris --- Diffs of the changes: (+4 -0) DAGCombiner.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.62 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.63 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.62 Fri Nov 11 18:59:01 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Dec 7 01:11:03 2005 @@ -1546,6 +1546,10 @@ // fold (sext (sextload x)) -> (sextload x) if (N0.getOpcode() == ISD::SEXTLOAD && VT == N0.getValueType()) return N0; + // fold (sext (truncate x)) -> (sextinreg x) iff x size == sext size. + if (N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getValueType() == VT) + return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), + DAG.getValueType(N0.getValueType())); // fold (sext (load x)) -> (sextload x) if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse()) { SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), From lattner at cs.uiuc.edu Wed Dec 7 11:59:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Dec 2005 11:59:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200512071759.LAA02799@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.5 -> 1.6 --- Log message: X86 doesn't support sextinreg for 8-bit things either. --- Diffs of the changes: (+1 -0) X86ISelLowering.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.5 llvm/lib/Target/X86/X86ISelLowering.cpp:1.6 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.5 Tue Nov 29 00:16:21 2005 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Dec 7 11:59:14 2005 @@ -88,6 +88,7 @@ setOperationAction(ISD::BRTWOWAY_CC , MVT::Other, Expand); setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand); + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); From lattner at cs.uiuc.edu Wed Dec 7 12:02:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Dec 2005 12:02:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200512071802.MAA03176@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.63 -> 1.64 --- Log message: Only transform (sext (truncate x)) -> (sextinreg x) if before legalize or if the target supports the resultant sextinreg --- Diffs of the changes: (+3 -1) DAGCombiner.cpp | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.63 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.64 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.63 Wed Dec 7 01:11:03 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Dec 7 12:02:05 2005 @@ -1547,7 +1547,9 @@ if (N0.getOpcode() == ISD::SEXTLOAD && VT == N0.getValueType()) return N0; // fold (sext (truncate x)) -> (sextinreg x) iff x size == sext size. - if (N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getValueType() == VT) + if (N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getValueType() == VT&& + (!AfterLegalize || + TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, N0.getValueType()))) return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), DAG.getValueType(N0.getValueType())); // fold (sext (load x)) -> (sextload x) From lattner at cs.uiuc.edu Wed Dec 7 13:35:22 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Dec 2005 13:35:22 -0600 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c Message-ID: <200512071935.NAA09345@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.120 -> 1.121 --- Log message: Minor simplification to the EH code: CleanupsCanThrow is always the inverse of isExceptionEdge. Eliminate it in favor of !isExceptionEdge --- Diffs of the changes: (+28 -41) llvm-expand.c | 69 +++++++++++++++++++++++----------------------------------- 1 files changed, 28 insertions(+), 41 deletions(-) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.120 llvm-gcc/gcc/llvm-expand.c:1.121 --- llvm-gcc/gcc/llvm-expand.c:1.120 Sun Dec 4 22:49:21 2005 +++ llvm-gcc/gcc/llvm-expand.c Wed Dec 7 13:35:10 2005 @@ -48,7 +48,6 @@ static void llvm_expand_constructor(llvm_function *Fn, tree exp, llvm_value *Dest, int isVolatile); static void llvm_expand_goto_internal(llvm_function *Fn, llvm_basicblock *label, - int CleanupsCanThrow, int isExceptionEdge); static llvm_constant *llvm_expand_constant_expr(tree exp, llvm_type *ReqType); static llvm_constant *llvm_decode_string_constant(tree exp, unsigned Len, @@ -638,10 +637,6 @@ /* The LLVM basic block that this is jumping to. */ llvm_basicblock *target_bb; - /* Information about what happens if a cleanup expression throws an exception. - See llvm_expand_goto_internal for information about this flag. */ - int CleanupsCanThrow : 1; - /* Information about whether this goto is part of an exception propagation. * If so, cleanups which are only supposed to be run on exception exits are * expanded. @@ -770,9 +765,8 @@ void llvm_fixup_list_dump(llvm_function *Fn) { llvm_goto_fixup *f = Fn->ExpandInfo->GotoFixupList; for (; f; f = f->next) { - fprintf(stderr, "Fixup [%p]: to bb %%%s cct: %s iee: %s cleanups: %p" + fprintf(stderr, "Fixup [%p]: to bb %%%s iee: %s cleanups: %p" " containing_block: %p\n", (void*)f, D2V(f->target_bb)->Name, - f->CleanupsCanThrow ? "Yes" : "No", f->isExceptionEdge ? "Yes" : "No", (void*)f->cleanup_list, (void*)f->containing_block); } @@ -784,13 +778,11 @@ */ static llvm_basicblock * llvm_get_existing_fixup(llvm_function *Fn, llvm_basicblock *BB, - int CleanupsCanThrow, int isExceptionEdge, - tree cleanups) { + int isExceptionEdge, tree cleanups) { llvm_goto_fixup *fixup; for (fixup = Fn->ExpandInfo->GotoFixupList; fixup; fixup = fixup->next) if (fixup->target_bb == BB && fixup->cleanup_list == cleanups && - fixup->CleanupsCanThrow == CleanupsCanThrow && fixup->isExceptionEdge == isExceptionEdge) { llvm_basicblock *FixupBrBlock = fixup->BranchBlock; @@ -835,14 +827,14 @@ */ static int llvm_expand_cleanups(llvm_function *Fn, tree *list, llvm_instruction *TheBranch, - int CleanupsCanThrow, int isExceptionEdge) { + int isExceptionEdge) { int CleanupIsDead = 0; tree OrigList = *list; assert(TheBranch->Opcode == O_Br && TheBranch->NumOperands == 1 && "Cleanups only support for unconditional branches!"); - if (!CleanupsCanThrow) + if (isExceptionEdge) Fn->ExpandInfo->ThrownExceptionsCallTerminate++; while (*list) { @@ -870,8 +862,8 @@ */ llvm_basicblock *DestBB = V2BB(TheBranch->Operands[0]); llvm_basicblock *Existing = llvm_get_existing_fixup(Fn, DestBB, - CleanupsCanThrow, - isExceptionEdge, *list); + isExceptionEdge, + *list); if (Existing) { TheBranch->Operands[0] = D2V(Existing); CleanupIsDead = 1; @@ -883,7 +875,7 @@ /* Restore input list to what it was when llvm_expand_cleanups was invoked */ *list = OrigList; - if (!CleanupsCanThrow) + if (isExceptionEdge) Fn->ExpandInfo->ThrownExceptionsCallTerminate--; return CleanupIsDead; @@ -931,7 +923,6 @@ DeleteThisFixup = llvm_expand_cleanups(Fn, &thisblock->x.block.cleanups, f->BranchInst, - f->CleanupsCanThrow, f->isExceptionEdge); thisblock->x.block.cleanups = SavedCleanups; @@ -989,7 +980,7 @@ /* Now that we have handled this binding level for the goto, check to see * if it became equal to an existing fixup. */ - LastBlock = llvm_get_existing_fixup(Fn, f->target_bb, f->CleanupsCanThrow, + LastBlock = llvm_get_existing_fixup(Fn, f->target_bb, f->isExceptionEdge, newcleanups); if (LastBlock) { @@ -1164,7 +1155,7 @@ AfterBlock = llvm_basicblock_new("after_region"); if (!EndOfFunctionUnreachable(Fn)) - llvm_expand_goto_internal(Fn, AfterBlock, 1, 0); + llvm_expand_goto_internal(Fn, AfterBlock, 0); } /* Pop the current scope off of the stack... */ @@ -1249,7 +1240,7 @@ void llvm_emit_code_for_throw(llvm_function *Fn) { llvm_basicblock *Dest = get_innermost_catch_block(Fn); - llvm_expand_goto_internal(Fn, Dest, 0, 1); + llvm_expand_goto_internal(Fn, Dest, 1); /* Start a new block so that if statements are emitted after the throw, that * they will have the correct "current block". @@ -1307,7 +1298,7 @@ /* Propagate control flow to a containing exception region or rethrow as necessary */ - llvm_expand_goto_internal(Fn, get_innermost_catch_block(Fn), 0, 1); + llvm_expand_goto_internal(Fn, get_innermost_catch_block(Fn), 1); llvm_emit_label(Fn, thisexcept.x.except.OutBlock); } else { @@ -1463,7 +1454,7 @@ /* If none of the handlers caught the exception, rethrow it by either branching to an catch block we are nested in, or by rethrowing the exception */ - llvm_expand_goto_internal(Fn, get_innermost_catch_block(Fn), 0, 1); + llvm_expand_goto_internal(Fn, get_innermost_catch_block(Fn), 1); /* Continue emitting code after the try block */ llvm_emit_label(Fn, thisexcept.x.except.OutBlock); @@ -1529,7 +1520,7 @@ /* If none of the handlers caught the exception, rethrow it by either branching to an catch block we are nested in, or by rethrowing the exception */ - llvm_expand_goto_internal(Fn, get_innermost_catch_block(Fn), 0, 1); + llvm_expand_goto_internal(Fn, get_innermost_catch_block(Fn), 1); /* Continue emitting code after the try block */ llvm_emit_label(Fn, thisexcept.x.except.OutBlock); @@ -1636,18 +1627,16 @@ * When the block containing the cleanup is exited, the end-of-block code * inserts the cleanups as indicated by goto_fixups. * - * If it is illegal for inserted cleanups to throw any exceptions, - * CleanupsCanThrow should be set to zero. This is an important case for - * exception handling: when unwinding the stack due to an active exception, any - * destructors which propagate exceptions should cause terminate to be called. + * If isExceptionEdge is true, cleanups which apply only to exceptions are + * expanded, otherwise they are not. Note that when isExceptionEdge is true, + * it is illegal for inserted cleanups to throw any exceptions. This is an + * important case for exception handling: when unwinding the stack due to an + * active exception, any destructors which propagate exceptions should cause + * terminate to be called. * Thus, if a cleanup can throw an exception, it's exception destination goes to * a designated terminate block. - * - * If isExceptionEdge is true, cleanups which apply only to exceptions are - * expanded, otherwise they are not. */ static void llvm_expand_goto_internal(llvm_function *Fn, llvm_basicblock *BB, - int CleanupsCanThrow, int isExceptionEdge) { /* Create the final branch we will be using */ llvm_instruction *Branch = create_uncond_branch(BB); @@ -1688,8 +1677,7 @@ /* Okay, now we know that we need a fixup for this block. Scan to see if any * identical fixups exist. If so, we can share the code between the branches. */ - ExistingFixupBlock = llvm_get_existing_fixup(Fn, BB, CleanupsCanThrow, - isExceptionEdge, + ExistingFixupBlock = llvm_get_existing_fixup(Fn, BB, isExceptionEdge, block->x.block.cleanups); if (ExistingFixupBlock) { /* Instead of jumping directly to BB, jump to fixup->BranchBlock @@ -1705,7 +1693,6 @@ fixup->BranchBlock = BranchBlock; fixup->BranchInst = Branch; fixup->target_bb = BB; - fixup->CleanupsCanThrow = CleanupsCanThrow; fixup->isExceptionEdge = isExceptionEdge; fixup->containing_block = block; fixup->cleanup_list = block->x.block.cleanups; @@ -1730,7 +1717,7 @@ Fn->ExpandInfo->CleanupBlock : Fn->ExpandInfo->ReturnBlock; /* Simply goto the exit label now. */ - llvm_expand_goto_internal(Fn, EndLabel, 1, 0); + llvm_expand_goto_internal(Fn, EndLabel, 0); /* Start a new block so that if statements are emitted after the return, that * they will have the correct "current block". @@ -1906,7 +1893,7 @@ return 0; whichloop->x.loop.ContinueFound = 1; - llvm_expand_goto_internal(Fn, whichloop->x.loop.continue_label, 1, 0); + llvm_expand_goto_internal(Fn, whichloop->x.loop.continue_label, 0); /* Start a new block so that if statements are emitted after the continue, * that they will have the correct "current block". @@ -1947,7 +1934,7 @@ if (integer_nonzerop(cond)) /* No exit can happen */ return 1; if (integer_zerop(cond)) { /* Exit is guaranteed to happen */ - llvm_expand_goto_internal(Fn, whichloop->x.loop.end_label, 1, 0); + llvm_expand_goto_internal(Fn, whichloop->x.loop.end_label, 0); return 1; } @@ -1972,7 +1959,7 @@ llvm_expand_goto_internal only operates on unconditional branches. */ llvm_basicblock *ExitHelperBlock =llvm_basicblock_new("exit_loop_cleanups"); append_inst(Fn, create_cond_branch(Cond, ContBlock, ExitHelperBlock)); - llvm_expand_goto_internal(Fn, whichloop->x.loop.end_label, 1, 0); + llvm_expand_goto_internal(Fn, whichloop->x.loop.end_label, 0); } llvm_emit_label(Fn, ContBlock); return 1; @@ -1993,7 +1980,7 @@ for (n = Fn->ExpandInfo->InnermostScope; n; n = n->all) if (n->exit_block) { n->BreakFound = 1; - llvm_expand_goto_internal(Fn, n->exit_block, 1, 0); + llvm_expand_goto_internal(Fn, n->exit_block, 0); /* Start a new block so that if statements are emitted after the break, * that they will have the correct "current block". @@ -2217,7 +2204,7 @@ * There should be one collector block per cleanup level! Note that * standard GCC gets this wrong as well. */ - llvm_expand_goto_internal(Fn, Fn->ExpandInfo->IndirectGotoBlock, 1, 0); + llvm_expand_goto_internal(Fn, Fn->ExpandInfo->IndirectGotoBlock, 0); /* Start a new block so that if statements are emitted after the goto, that * they will have the correct "current block". @@ -2227,7 +2214,7 @@ } TREE_USED(dest) = 1; - llvm_expand_goto_internal(Fn, getLabelDeclBlock(dest), 1, 0); + llvm_expand_goto_internal(Fn, getLabelDeclBlock(dest), 0); /* Start a new block so that if statements are emitted after the goto, that * they will have the correct "current block". @@ -3215,7 +3202,7 @@ Call->Operands[2] = D2V(CleanupDest); append_inst(Fn, Call); llvm_emit_label(Fn, CleanupDest); - llvm_expand_goto_internal(Fn, ExceptBlock, 0, 1); + llvm_expand_goto_internal(Fn, ExceptBlock, 1); } llvm_emit_label(Fn, NormalDest); } From natebegeman at mac.com Wed Dec 7 13:48:22 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 7 Dec 2005 13:48:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAGISel.cpp Message-ID: <200512071948.NAA09416@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.223 -> 1.224 SelectionDAGISel.cpp updated: 1.111 -> 1.112 --- Log message: Fix a crash where ConstantVec nodes were being generated with the wrong type when the target did not support them. Also teach Legalize how to expand ConstantVecs. This allows us to generate _test: lwz r2, 12(r3) lwz r4, 8(r3) lwz r5, 4(r3) lwz r6, 0(r3) addi r2, r2, 4 addi r4, r4, 3 addi r5, r5, 2 addi r6, r6, 1 stw r2, 12(r3) stw r4, 8(r3) stw r5, 4(r3) stw r6, 0(r3) blr For: void %test(%v4i *%P) { %T = load %v4i* %P %S = add %v4i %T, store %v4i %S, %v4i * %P ret void } On PowerPC. --- Diffs of the changes: (+30 -2) LegalizeDAG.cpp | 22 ++++++++++++++++++++++ SelectionDAGISel.cpp | 10 ++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.223 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.224 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.223 Tue Dec 6 00:18:55 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Dec 7 13:48:11 2005 @@ -3159,6 +3159,28 @@ Hi = DAG.getConstant(Cst >> MVT::getSizeInBits(NVT), NVT); break; } + case ISD::ConstantVec: { + unsigned NumElements = Node->getNumOperands(); + // If we only have two elements left in the constant vector, just break it + // apart into the two scalar constants it contains. Otherwise, bisect the + // ConstantVec, and return each half as a new ConstantVec. + // FIXME: this is hard coded as big endian, it may have to change to support + // SSE and Alpha MVI + if (NumElements == 2) { + Hi = Node->getOperand(0); + Lo = Node->getOperand(1); + } else { + NumElements /= 2; + std::vector LoOps, HiOps; + for (unsigned I = 0, E = NumElements; I < E; ++I) { + HiOps.push_back(Node->getOperand(I)); + LoOps.push_back(Node->getOperand(I+NumElements)); + } + Lo = DAG.getNode(ISD::ConstantVec, MVT::Vector, LoOps); + Hi = DAG.getNode(ISD::ConstantVec, MVT::Vector, HiOps); + } + break; + } case ISD::BUILD_PAIR: // Legalize both operands. FIXME: in the future we should handle the case Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.111 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.112 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.111 Tue Dec 6 00:18:55 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Dec 7 13:48:11 2005 @@ -318,9 +318,15 @@ } // Handle the case where we have a 1-element vector, in which // case we want to immediately turn it into a scalar constant. - if (Ops.size() == 1) + if (Ops.size() == 1) { return N = Ops[0]; - return N = DAG.getNode(ISD::ConstantVec, TVT, Ops); + } else if (TVT != MVT::Other && TLI.isTypeLegal(TVT)) { + return N = DAG.getNode(ISD::ConstantVec, TVT, Ops); + } else { + // If the packed type isn't legal, then create a ConstantVec node with + // generic Vector type instead. + return N = DAG.getNode(ISD::ConstantVec, MVT::Vector, Ops); + } } else { // Canonicalize all constant ints to be unsigned. return N = DAG.getConstant(cast(C)->getRawValue(),VT); From evan.cheng at apple.com Wed Dec 7 20:00:48 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 7 Dec 2005 20:00:48 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200512080200.UAA00584@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.75 -> 1.76 --- Log message: Added support for ComplexPattern. These are patterns that require C++ pattern matching code that is not currently auto-generated by tblgen, e.g. X86 addressing mode. Selection routines for complex patterns can return multiple operands, e.g. X86 addressing mode returns 4. --- Diffs of the changes: (+49 -10) SelectionDAG.h | 59 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 49 insertions(+), 10 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.75 llvm/include/llvm/CodeGen/SelectionDAG.h:1.76 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.75 Wed Nov 30 18:18:45 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Wed Dec 7 20:00:35 2005 @@ -327,16 +327,6 @@ SDOperand Op1, SDOperand Op2) { return getNode(ISD::BUILTIN_OP_END+Opcode, VT, Op1, Op2); } - SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT1, - MVT::ValueType VT2, SDOperand Op1, SDOperand Op2) { - std::vector ResultTys; - ResultTys.push_back(VT1); - ResultTys.push_back(VT2); - std::vector Ops; - Ops.push_back(Op1); - Ops.push_back(Op2); - return getNode(ISD::BUILTIN_OP_END+Opcode, ResultTys, Ops); - } SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT, SDOperand Op1, SDOperand Op2, SDOperand Op3) { return getNode(ISD::BUILTIN_OP_END+Opcode, VT, Op1, Op2, Op3); @@ -355,6 +345,55 @@ std::vector &Ops) { return getNode(ISD::BUILTIN_OP_END+Opcode, VT, Ops); } + SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT1, + MVT::ValueType VT2, SDOperand Op1, SDOperand Op2) { + std::vector ResultTys; + ResultTys.push_back(VT1); + ResultTys.push_back(VT2); + std::vector Ops; + Ops.push_back(Op1); + Ops.push_back(Op2); + return getNode(ISD::BUILTIN_OP_END+Opcode, ResultTys, Ops); + } + SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT1, + MVT::ValueType VT2, SDOperand Op1, SDOperand Op2, + SDOperand Op3) { + std::vector ResultTys; + ResultTys.push_back(VT1); + ResultTys.push_back(VT2); + std::vector Ops; + Ops.push_back(Op1); + Ops.push_back(Op2); + Ops.push_back(Op3); + return getNode(ISD::BUILTIN_OP_END+Opcode, ResultTys, Ops); + } + SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT1, + MVT::ValueType VT2, SDOperand Op1, SDOperand Op2, + SDOperand Op3, SDOperand Op4) { + std::vector ResultTys; + ResultTys.push_back(VT1); + ResultTys.push_back(VT2); + std::vector Ops; + Ops.push_back(Op1); + Ops.push_back(Op2); + Ops.push_back(Op3); + Ops.push_back(Op4); + return getNode(ISD::BUILTIN_OP_END+Opcode, ResultTys, Ops); + } + SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT1, + MVT::ValueType VT2, SDOperand Op1, SDOperand Op2, + SDOperand Op3, SDOperand Op4, SDOperand Op5) { + std::vector ResultTys; + ResultTys.push_back(VT1); + ResultTys.push_back(VT2); + std::vector Ops; + Ops.push_back(Op1); + Ops.push_back(Op2); + Ops.push_back(Op3); + Ops.push_back(Op4); + Ops.push_back(Op5); + return getNode(ISD::BUILTIN_OP_END+Opcode, ResultTys, Ops); + } SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT1, MVT::ValueType VT2, std::vector &Ops) { std::vector ResultTys; From evan.cheng at apple.com Wed Dec 7 20:00:48 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 7 Dec 2005 20:00:48 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenTarget.cpp CodeGenTarget.h DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200512080200.UAA00596@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenTarget.cpp updated: 1.47 -> 1.48 CodeGenTarget.h updated: 1.21 -> 1.22 DAGISelEmitter.cpp updated: 1.85 -> 1.86 DAGISelEmitter.h updated: 1.39 -> 1.40 --- Log message: Added support for ComplexPattern. These are patterns that require C++ pattern matching code that is not currently auto-generated by tblgen, e.g. X86 addressing mode. Selection routines for complex patterns can return multiple operands, e.g. X86 addressing mode returns 4. --- Diffs of the changes: (+171 -47) CodeGenTarget.cpp | 9 ++ CodeGenTarget.h | 17 +++++ DAGISelEmitter.cpp | 165 ++++++++++++++++++++++++++++++++++++++++------------- DAGISelEmitter.h | 27 +++++--- 4 files changed, 171 insertions(+), 47 deletions(-) Index: llvm/utils/TableGen/CodeGenTarget.cpp diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.47 llvm/utils/TableGen/CodeGenTarget.cpp:1.48 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.47 Sun Dec 4 02:18:16 2005 +++ llvm/utils/TableGen/CodeGenTarget.cpp Wed Dec 7 20:00:36 2005 @@ -330,3 +330,12 @@ throw "Instruction '" + TheDef->getName() + "' does not have an operand named '$" + Name + "'!"; } + +//===----------------------------------------------------------------------===// +// ComplexPattern implementation +// +ComplexPattern::ComplexPattern(Record *R) { + NumOperands = R->getValueAsInt("NumOperands"); + SelectFunc = R->getValueAsString("SelectFunc"); + MatchingNodes = R->getValueAsListOfDefs("MatchingNodes"); +} Index: llvm/utils/TableGen/CodeGenTarget.h diff -u llvm/utils/TableGen/CodeGenTarget.h:1.21 llvm/utils/TableGen/CodeGenTarget.h:1.22 --- llvm/utils/TableGen/CodeGenTarget.h:1.21 Sun Dec 4 20:35:08 2005 +++ llvm/utils/TableGen/CodeGenTarget.h Wed Dec 7 20:00:36 2005 @@ -157,6 +157,23 @@ bool isLittleEndianEncoding() const; }; +/// ComplexPattern - ComplexPattern info, corresponding to the ComplexPattern +/// tablegen class in TargetSelectionDAG.td +class ComplexPattern { + unsigned NumOperands; + std::string SelectFunc; + std::vector MatchingNodes; +public: + ComplexPattern() : NumOperands(0) {}; + ComplexPattern(Record *R); + + unsigned getNumOperands() const { return NumOperands; } + const std::string &getSelectFunc() const { return SelectFunc; } + const std::vector &getMatchingNodes() const { + return MatchingNodes; + } +}; + } // End llvm namespace #endif Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.85 llvm/utils/TableGen/DAGISelEmitter.cpp:1.86 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.85 Mon Dec 5 17:08:55 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed Dec 7 20:00:36 2005 @@ -477,6 +477,9 @@ } else if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) { // Using a VTSDNode or CondCodeSDNode. return MVT::Other; + } else if (R->isSubClassOf("ComplexPattern")) { + const CodeGenTarget &T = TP.getDAGISelEmitter().getTargetInfo(); + return T.getPointerType(); } else if (R->getName() == "node") { // Placeholder. return MVT::isUnknown; @@ -609,7 +612,7 @@ 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()); @@ -833,6 +836,13 @@ } } +void DAGISelEmitter::ParseComplexPatterns() { + std::vector AMs = Records.getAllDerivedDefinitions("ComplexPattern"); + while (!AMs.empty()) { + ComplexPatterns.insert(std::make_pair(AMs.back(), AMs.back())); + AMs.pop_back(); + } +} /// ParsePatternFragments - Parse all of the PatFrag definitions in the .td @@ -1204,9 +1214,10 @@ if (InVal->isLeaf() && dynamic_cast(InVal->getLeafValue())) { Record *InRec = static_cast(InVal->getLeafValue())->getDef(); - if (CGI.OperandList[i].Rec != InRec) + if (CGI.OperandList[i].Rec != InRec && + !InRec->isSubClassOf("ComplexPattern")) I->error("Operand $" + OpName + - "'s register class disagrees between the operand and pattern"); + "'s register class disagrees between the operand and pattern"); } Operands.push_back(CGI.OperandList[i].Rec); @@ -1586,22 +1597,59 @@ } +// NodeIsComplexPattern - return true if N is a leaf node and a subclass of +// ComplexPattern. +static bool NodeIsComplexPattern(TreePatternNode *N) +{ + return (N->isLeaf() && + dynamic_cast(N->getLeafValue()) && + static_cast(N->getLeafValue())->getDef()-> + isSubClassOf("ComplexPattern")); +} + +// NodeGetComplexPattern - return the pointer to the ComplexPattern if N +// is a leaf node and a subclass of ComplexPattern, else it returns NULL. +static const ComplexPattern *NodeGetComplexPattern(TreePatternNode *N, + DAGISelEmitter &ISE) +{ + if (N->isLeaf() && + dynamic_cast(N->getLeafValue()) && + static_cast(N->getLeafValue())->getDef()-> + isSubClassOf("ComplexPattern")) { + return &ISE.getComplexPattern(static_cast(N->getLeafValue()) + ->getDef()); + } + return NULL; +} + /// 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) { +static unsigned getPatternSize(TreePatternNode *P, DAGISelEmitter &ISE) { assert(isExtIntegerVT(P->getExtType()) || isExtFloatingPointVT(P->getExtType()) || P->getExtType() == MVT::isVoid && "Not a valid pattern node to size!"); unsigned Size = 1; // The node itself. - + + // FIXME: This is a hack to statically increase the priority of patterns + // which maps a sub-dag to a complex pattern. e.g. favors LEA over ADD. + // Later we can allow complexity / cost for each pattern to be (optionally) + // specified. To get best possible pattern match we'll need to dynamically + // calculate the complexity of all patterns a dag can potentially map to. + const ComplexPattern *AM = NodeGetComplexPattern(P, ISE); + if (AM) + Size += AM->getNumOperands(); + // 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->getExtType() != MVT::Other) - Size += getPatternSize(Child); - else if (Child->isLeaf() && dynamic_cast(Child->getLeafValue())) { - ++Size; // Matches a ConstantSDNode. + Size += getPatternSize(Child, ISE); + else if (Child->isLeaf()) { + if (dynamic_cast(Child->getLeafValue())) + ++Size; // Matches a ConstantSDNode. + else if (NodeIsComplexPattern(Child)) + Size += getPatternSize(Child, ISE); } } @@ -1624,10 +1672,13 @@ // In particular, we want to match maximal patterns first and lowest cost within // a particular complexity first. struct PatternSortingPredicate { + PatternSortingPredicate(DAGISelEmitter &ise) : ISE(ise) {}; + DAGISelEmitter &ISE; + bool operator()(DAGISelEmitter::PatternToMatch *LHS, DAGISelEmitter::PatternToMatch *RHS) { - unsigned LHSSize = getPatternSize(LHS->first); - unsigned RHSSize = getPatternSize(RHS->first); + unsigned LHSSize = getPatternSize(LHS->first, ISE); + unsigned RHSSize = getPatternSize(RHS->first, ISE); if (LHSSize > RHSSize) return true; // LHS -> bigger -> less cost if (LHSSize < RHSSize) return false; @@ -1649,9 +1700,10 @@ << ")->getSignExtended() != " << II->getValue() << ")\n" << " goto P" << PatternNo << "Fail;\n"; return; + } else if (!NodeIsComplexPattern(N)) { + assert(0 && "Cannot match this as a leaf value!"); + abort(); } - assert(0 && "Cannot match this as a leaf value!"); - abort(); } // If this node has a name associated with it, capture it in VarMap. If @@ -1710,6 +1762,8 @@ if (LeafRec->isSubClassOf("RegisterClass") || LeafRec->isSubClassOf("Register")) { // Handle register references. Nothing to do here. + } else if (LeafRec->isSubClassOf("ComplexPattern")) { + // Handle complex pattern. Nothing to do here. } else if (LeafRec->isSubClassOf("ValueType")) { // Make sure this is the specified value type. OS << " if (cast(" << RootName << OpNo << ")->getVT() != " @@ -1819,9 +1873,10 @@ /// CodeGenPatternResult - Emit the action for a pattern. Now that it has /// matched, we actually have to build a DAG! -unsigned DAGISelEmitter:: +std::pair DAGISelEmitter:: CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, std::map &VariableMap, + unsigned PatternNo, std::ostream &OS, bool &HasChain, bool InFlag, bool isRoot) { // This is something selected from the pattern we matched. @@ -1832,10 +1887,12 @@ "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. - return atoi(Val.c_str()+3); + return std::make_pair(1, atoi(Val.c_str()+3)); } - + + const ComplexPattern *CP; unsigned ResNo = Ctr++; + unsigned NumRes = 1; if (!N->isLeaf() && N->getOperator()->getName() == "imm") { switch (N->getType()) { default: assert(0 && "Unknown type for constant node!"); @@ -1850,13 +1907,27 @@ << ResNo << "C, MVT::" << getEnumName(N->getType()) << ");\n"; } else if (!N->isLeaf() && N->getOperator()->getName() == "tglobaladdr") { OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; + } else if (N->isLeaf() && (CP = NodeGetComplexPattern(N, *this))) { + std::string Fn = CP->getSelectFunc(); + NumRes = CP->getNumOperands(); + OS << " SDOperand "; + for (unsigned i = 0; i < NumRes; i++) { + if (i != 0) OS << ", "; + OS << "Tmp" << i + ResNo; + } + OS << ";\n"; + OS << " if (!" << Fn << "(" << Val; + for (unsigned i = 0; i < NumRes; i++) + OS << " , Tmp" << i + ResNo; + OS << ")) goto P" << PatternNo << "Fail;\n"; + Ctr = ResNo + NumRes; } else { 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; + return std::make_pair(NumRes, ResNo); } if (N->isLeaf()) { @@ -1868,7 +1939,7 @@ << getQualifiedName(DI->getDef()) << ", MVT::" << getEnumName(N->getType()) << ");\n"; - return ResNo; + return std::make_pair(1, ResNo); } } else if (IntInit *II = dynamic_cast(N->getLeafValue())) { unsigned ResNo = Ctr++; @@ -1876,21 +1947,26 @@ << II->getValue() << ", MVT::" << getEnumName(N->getType()) << ");\n"; - return ResNo; + return std::make_pair(1, ResNo); } N->dump(); assert(0 && "Unknown leaf type!"); - return ~0U; + return std::make_pair(1, ~0U); } Record *Op = N->getOperator(); if (Op->isSubClassOf("Instruction")) { // Emit all of the operands. std::vector Ops; - for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) - Ops.push_back(CodeGenPatternResult(N->getChild(i), Ctr, - VariableMap, OS, HasChain, InFlag)); + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { + TreePatternNode *Child = N->getChild(i); + std::pair NOPair = + CodeGenPatternResult(Child, Ctr, + VariableMap, PatternNo, OS, HasChain, InFlag); + for (unsigned j = 0; j < NOPair.first; j++) + Ops.push_back(NOPair.second + j); + } CodeGenInstruction &II = Target.getInstruction(Op->getName()); bool HasCtrlDep = II.hasCtrlDep; @@ -1934,12 +2010,12 @@ OS << " CodeGenMap[N.getValue(0)] = Result;\n"; OS << " CodeGenMap[N.getValue(" << NumResults << ")] = Result.getValue(" << NumResults << ");\n"; - OS << " Chain = CodeGenMap[N].getValue(" << NumResults << ");\n"; + OS << " Chain = Result.getValue(" << NumResults << ");\n"; } if (NumResults == 0) OS << " return Chain;\n"; else - OS << " return (N.ResNo) ? Chain : CodeGenMap[N];\n"; + OS << " return (N.ResNo) ? Chain : Result.getValue(0);\n"; } else { // If this instruction is the root, and if there is only one use of it, // use SelectNodeTo instead of getTargetNode to avoid an allocation. @@ -1963,11 +2039,12 @@ OS << ");\n"; OS << " }\n"; } - return ResNo; + return std::make_pair(1, ResNo); } else if (Op->isSubClassOf("SDNodeXForm")) { assert(N->getNumChildren() == 1 && "node xform should have one child!"); unsigned OpVal = CodeGenPatternResult(N->getChild(0), Ctr, - VariableMap, OS, HasChain, InFlag); + VariableMap, PatternNo, OS, HasChain, InFlag) + .second; unsigned ResNo = Ctr++; OS << " SDOperand Tmp" << ResNo << " = Transform_" << Op->getName() @@ -1976,11 +2053,11 @@ OS << " CodeGenMap[N] = Tmp" << ResNo << ";\n"; OS << " return Tmp" << ResNo << ";\n"; } - return ResNo; + return std::make_pair(1, ResNo); } else { N->dump(); assert(0 && "Unknown node in result pattern!"); - return ~0U; + return std::make_pair(1, ~0U); } } @@ -2005,10 +2082,13 @@ if (!Pat->hasTypeSet()) { // Move a type over from 'other' to 'pat'. Pat->setType(Other->getType()); - OS << " if (" << Prefix << ".getValueType() != MVT::" + OS << " if (" << Prefix << ".Val->getValueType(0) != MVT::" << getName(Pat->getType()) << ") goto P" << PatternNo << "Fail;\n"; return true; } else if (Pat->isLeaf()) { + if (NodeIsComplexPattern(Pat)) + OS << " if (" << Prefix << ".Val->getValueType(0) != MVT::" + << getName(Pat->getType()) << ") goto P" << PatternNo << "Fail;\n"; return false; } @@ -2038,7 +2118,7 @@ OS << "\n // Emits: "; Pattern.second->print(OS); OS << "\n"; - OS << " // Pattern complexity = " << getPatternSize(Pattern.first) + OS << " // Pattern complexity = " << getPatternSize(Pattern.first, *this) << " cost = " << getResultPatternCost(Pattern.second) << "\n"; // Emit the matcher, capturing named arguments in VariableMap. @@ -2088,7 +2168,7 @@ unsigned TmpNo = 0; CodeGenPatternResult(Pattern.second, - TmpNo, VariableMap, OS, HasChain, InFlag, true /*the root*/); + TmpNo, VariableMap, PatternNo, OS, HasChain, InFlag, true /*the root*/); delete Pat; OS << " }\n P" << PatternNo << "Fail:\n"; @@ -2166,23 +2246,31 @@ // Group the patterns by their top-level opcodes. std::map, CompareByRecordName> PatternsByOpcode; - for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) - if (!PatternsToMatch[i].first->isLeaf()) { - PatternsByOpcode[PatternsToMatch[i].first->getOperator()] - .push_back(&PatternsToMatch[i]); + for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) { + TreePatternNode *Node = PatternsToMatch[i].first; + if (!Node->isLeaf()) { + PatternsByOpcode[Node->getOperator()].push_back(&PatternsToMatch[i]); } else { + const ComplexPattern *CP; if (IntInit *II = - dynamic_cast(PatternsToMatch[i].first->getLeafValue())) { + dynamic_cast(Node->getLeafValue())) { PatternsByOpcode[getSDNodeNamed("imm")].push_back(&PatternsToMatch[i]); + } else if ((CP = NodeGetComplexPattern(Node, *this))) { + std::vector OpNodes = CP->getMatchingNodes(); + for (unsigned j = 0, e = OpNodes.size(); j != e; j++) { + PatternsByOpcode[OpNodes[j]].insert(PatternsByOpcode[OpNodes[j]].begin(), + &PatternsToMatch[i]); + } } else { std::cerr << "Unrecognized opcode '"; - PatternsToMatch[i].first->dump(); + Node->dump(); std::cerr << "' on tree pattern '"; std::cerr << PatternsToMatch[i].second->getOperator()->getName(); std::cerr << "'!\n"; exit(1); } } + } // Loop over all of the case statements. for (std::map, @@ -2197,7 +2285,7 @@ // the matches in order of minimal cost. Sort the patterns so the least // cost one is at the start. std::stable_sort(Patterns.begin(), Patterns.end(), - PatternSortingPredicate()); + PatternSortingPredicate(*this)); for (unsigned i = 0, e = Patterns.size(); i != e; ++i) EmitCodeForPattern(*Patterns[i], OS); @@ -2227,6 +2315,7 @@ ParseNodeInfo(); ParseNodeTransforms(OS); + ParseComplexPatterns(); ParsePatternFragments(OS); ParseInstructions(); ParsePatterns(); Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.39 llvm/utils/TableGen/DAGISelEmitter.h:1.40 --- llvm/utils/TableGen/DAGISelEmitter.h:1.39 Sun Dec 4 02:18:16 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Wed Dec 7 20:00:36 2005 @@ -26,6 +26,7 @@ class TreePattern; class TreePatternNode; class DAGISelEmitter; + class ComplexPattern; /// MVT::DAGISelGenValueType - These are some extended forms of MVT::ValueType /// that we use as lattice values during type inferrence. @@ -365,6 +366,7 @@ std::map SDNodes; std::map > SDNodeXForms; + std::map ComplexPatterns; std::map PatternFragments; std::map Instructions; @@ -387,15 +389,20 @@ return SDNodes.find(R)->second; } - TreePattern *getPatternFragment(Record *R) const { - assert(PatternFragments.count(R) && "Invalid pattern fragment request!"); - return PatternFragments.find(R)->second; - } - const std::pair &getSDNodeTransform(Record *R) const { assert(SDNodeXForms.count(R) && "Invalid transform!"); return SDNodeXForms.find(R)->second; } + + const ComplexPattern &getComplexPattern(Record *R) const { + assert(ComplexPatterns.count(R) && "Unknown addressing mode!"); + return ComplexPatterns.find(R)->second; + } + + TreePattern *getPatternFragment(Record *R) const { + assert(PatternFragments.count(R) && "Invalid pattern fragment request!"); + return PatternFragments.find(R)->second; + } const DAGInstruction &getInstruction(Record *R) const { assert(Instructions.count(R) && "Unknown instruction!"); @@ -405,6 +412,7 @@ private: void ParseNodeInfo(); void ParseNodeTransforms(std::ostream &OS); + void ParseComplexPatterns(); void ParsePatternFragments(std::ostream &OS); void ParseInstructions(); void ParsePatterns(); @@ -420,10 +428,11 @@ std::ostream &OS, bool &HasChain); void EmitCopyToRegsForPattern(TreePatternNode *N, const std::string &RootName, std::ostream &OS, bool &HasChain, bool &InFlag); - unsigned CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, - std::map &VariableMap, - std::ostream &OS, bool &HasChain, bool InFlag, - bool isRoot = false); + std::pair + CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, + std::map &VariableMap, + unsigned PatternNo, std::ostream &OS, bool &HasChain, + bool InFlag, bool isRoot = false); void EmitCodeForPattern(PatternToMatch &Pattern, std::ostream &OS); void EmitInstructionSelector(std::ostream &OS); }; From evan.cheng at apple.com Wed Dec 7 20:01:47 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 7 Dec 2005 20:01:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp X86InstrInfo.td Message-ID: <200512080201.UAA00620@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.6 -> 1.7 X86InstrInfo.td updated: 1.148 -> 1.149 --- Log message: * Added intelligence to X86 LEA addressing mode matching routine so it returns false if the match is not profitable. e.g. leal 1(%eax), %eax. * Added patterns for X86 integer loads and LEA32. --- Diffs of the changes: (+103 -84) X86ISelDAGToDAG.cpp | 158 +++++++++++++++++++++++++++------------------------- X86InstrInfo.td | 29 +++++---- 2 files changed, 103 insertions(+), 84 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.6 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.7 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.6 Wed Nov 30 18:43:55 2005 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Dec 7 20:01:35 2005 @@ -36,6 +36,7 @@ enum { RegBase, FrameIndexBase, + ConstantPoolBase } BaseType; struct { // This is really a union, discriminated by BaseType! @@ -94,8 +95,11 @@ private: SDOperand Select(SDOperand N); - void SelectAddress(SDOperand N, X86ISelAddressMode &AM); bool MatchAddress(SDOperand N, X86ISelAddressMode &AM); + bool SelectAddr(SDOperand N, SDOperand &Base, SDOperand &Scale, + SDOperand &Index, SDOperand &Disp); + bool SelectLEAAddr(SDOperand N, SDOperand &Base, SDOperand &Scale, + SDOperand &Index, SDOperand &Disp); /// getI8Imm - Return a target constant with the specified value, of type /// i8. @@ -130,23 +134,6 @@ ScheduleAndEmitDAG(DAG); } -/// SelectAddress - Pattern match the maximal addressing mode for this node. -void X86DAGToDAGISel::SelectAddress(SDOperand N, X86ISelAddressMode &AM) { - MatchAddress(N, AM); - - if (AM.BaseType == X86ISelAddressMode::RegBase) { - if (AM.Base.Reg.Val) - AM.Base.Reg = Select(AM.Base.Reg); - else - AM.Base.Reg = CurDAG->getRegister(0, MVT::i32); - } - if (!AM.IndexReg.Val) { - AM.IndexReg = CurDAG->getRegister(0, MVT::i32); - } else { - AM.IndexReg = Select(AM.IndexReg); - } -} - /// FIXME: copied from X86ISelPattern.cpp /// MatchAddress - Add the specified node to the specified addressing mode, /// returning true if it cannot be done. This just pattern matches for the @@ -161,6 +148,17 @@ return false; } break; + + case ISD::ConstantPool: + if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) { + if (ConstantPoolSDNode *CP = dyn_cast(N)) { + AM.BaseType = X86ISelAddressMode::ConstantPoolBase; + AM.Base.Reg = CurDAG->getTargetConstantPool(CP->get(), MVT::i32); + return false; + } + } + break; + case ISD::GlobalAddress: if (AM.GV == 0) { GlobalValue *GV = cast(N)->getGlobal(); @@ -177,9 +175,11 @@ } } break; + case ISD::Constant: AM.Disp += cast(N)->getValue(); return false; + case ISD::SHL: if (AM.IndexReg.Val == 0 && AM.Scale == 1) if (ConstantSDNode *CN = dyn_cast(N.Val->getOperand(1))) { @@ -204,6 +204,7 @@ } } break; + case ISD::MUL: // X*[3,5,9] -> X+X*[2,4,8] if (AM.IndexReg.Val == 0 && AM.BaseType == X86ISelAddressMode::RegBase && @@ -266,6 +267,67 @@ return false; } +/// SelectAddr - returns true if it is able pattern match an addressing mode. +/// It returns the operands which make up the maximal addressing mode it can +/// match by reference. +bool X86DAGToDAGISel::SelectAddr(SDOperand N, SDOperand &Base, SDOperand &Scale, + SDOperand &Index, SDOperand &Disp) { + X86ISelAddressMode AM; + if (!MatchAddress(N, AM)) { + if (AM.BaseType == X86ISelAddressMode::RegBase) { + if (AM.Base.Reg.Val) + AM.Base.Reg = Select(AM.Base.Reg); + else + AM.Base.Reg = CurDAG->getRegister(0, MVT::i32); + } + if (AM.IndexReg.Val) + AM.IndexReg = Select(AM.IndexReg); + else + AM.IndexReg = CurDAG->getRegister(0, MVT::i32); + + Base = (AM.BaseType == X86ISelAddressMode::FrameIndexBase) ? + CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, MVT::i32) : AM.Base.Reg; + Scale = getI8Imm (AM.Scale); + Index = AM.IndexReg; + Disp = AM.GV ? CurDAG->getTargetGlobalAddress(AM.GV, MVT::i32, AM.Disp) + : getI32Imm(AM.Disp); + return true; + } + return false; +} + +static bool isRegister0(SDOperand Op) +{ + if (RegisterSDNode *R = dyn_cast(Op)) + return (R->getReg() == 0); + return false; +} + +/// SelectLEAAddr - it calls SelectAddr and determines if the maximal addressing +/// mode it matches can be cost effectively emitted as an LEA instruction. +/// For X86, it always is unless it's just a (Reg + const). +bool X86DAGToDAGISel::SelectLEAAddr(SDOperand N, SDOperand &Base, SDOperand &Scale, + SDOperand &Index, SDOperand &Disp) { + if (SelectAddr(N, Base, Scale, Index, Disp)) { + if (!isRegister0(Base)) { + unsigned Complexity = 0; + if ((unsigned)cast(Scale)->getValue() > 1) + Complexity++; + if (!isRegister0(Index)) + Complexity++; + if (ConstantSDNode *CN = dyn_cast(Disp)) { + if (!CN->isNullValue()) Complexity++; + } else { + Complexity++; + } + return (Complexity > 1); + } + return true; + } else { + return false; + } +} + SDOperand X86DAGToDAGISel::Select(SDOperand Op) { SDNode *N = Op.Val; MVT::ValueType OpVT = N->getValueType(0); @@ -326,51 +388,9 @@ Chain); } - case ISD::LOAD: { - switch (OpVT) { - default: assert(0 && "Cannot load this type!"); - case MVT::i1: - case MVT::i8: Opc = X86::MOV8rm; break; - case MVT::i16: Opc = X86::MOV16rm; break; - case MVT::i32: Opc = X86::MOV32rm; break; - case MVT::f32: Opc = X86::MOVSSrm; break; - case MVT::f64: Opc = X86::FLD64m; ContainsFPCode = true; break; - } - - if (ConstantPoolSDNode *CP = dyn_cast(N->getOperand(1))){ - unsigned CPIdx = BB->getParent()->getConstantPool()-> - getConstantPoolIndex(CP->get()); - // ??? - assert(0 && "Can't handle load from constant pool!"); - } else { - X86ISelAddressMode AM; - SDOperand Chain = Select(N->getOperand(0)); // Token chain. - - SelectAddress(N->getOperand(1), AM); - SDOperand Scale = getI8Imm (AM.Scale); - SDOperand Disp = AM.GV - ? CurDAG->getTargetGlobalAddress(AM.GV, MVT::i32, AM.Disp) - : getI32Imm(AM.Disp); - if (AM.BaseType == X86ISelAddressMode::RegBase) { - return CurDAG->SelectNodeTo(N, Opc, OpVT, MVT::Other, - AM.Base.Reg, Scale, AM.IndexReg, Disp, - Chain) - .getValue(Op.ResNo); - } else { - SDOperand Base = CurDAG->getFrameIndex(AM.Base.FrameIndex, MVT::i32); - return CurDAG->SelectNodeTo(N, Opc, OpVT, MVT::Other, - Base, Scale, AM.IndexReg, Disp, Chain) - .getValue(Op.ResNo); - } - } - } - case ISD::STORE: { SDOperand Chain = Select(N->getOperand(0)); // Token chain. SDOperand Tmp1 = Select(N->getOperand(1)); - X86ISelAddressMode AM; - SelectAddress(N->getOperand(2), AM); - Opc = 0; if (ConstantSDNode *CN = dyn_cast(N->getOperand(1))) { switch (CN->getValueType(0)) { @@ -394,19 +414,11 @@ } } - SDOperand Scale = getI8Imm (AM.Scale); - SDOperand Disp = AM.GV - ? CurDAG->getTargetGlobalAddress(AM.GV, MVT::i32, AM.Disp) - : getI32Imm(AM.Disp); - if (AM.BaseType == X86ISelAddressMode::RegBase) { - return CurDAG->SelectNodeTo(N, Opc, MVT::Other, - AM.Base.Reg, Scale, AM.IndexReg, Disp, Tmp1, - Chain); - } else { - SDOperand Base = CurDAG->getFrameIndex(AM.Base.FrameIndex, MVT::i32); - return CurDAG->SelectNodeTo(N, Opc, MVT::Other, - Base, Scale, AM.IndexReg, Disp, Tmp1, Chain); - } + SDOperand Base, Scale, Index, Disp; + SelectAddr(N->getOperand(2), Base, Scale, Index, Disp); + return CurDAG->SelectNodeTo(N, Opc, MVT::Other, + Base, Scale, Index, Disp, Tmp1, Chain) + .getValue(Op.ResNo); } } Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.148 llvm/lib/Target/X86/X86InstrInfo.td:1.149 --- llvm/lib/Target/X86/X86InstrInfo.td:1.148 Mon Dec 5 17:09:43 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Dec 7 20:01:35 2005 @@ -21,13 +21,13 @@ let MIOperandInfo = (ops R32, i8imm, R32, i32imm); } -def i8mem : X86MemOperand; -def i16mem : X86MemOperand; +def i8mem : X86MemOperand; +def i16mem : X86MemOperand; def i32mem : X86MemOperand; -def i64mem : X86MemOperand; -def f32mem : X86MemOperand; -def f64mem : X86MemOperand; -def f80mem : X86MemOperand; +def i64mem : X86MemOperand; +def f32mem : X86MemOperand; +def f64mem : X86MemOperand; +def f80mem : X86MemOperand; def SSECC : Operand { let PrintMethod = "printSSECC"; @@ -46,6 +46,10 @@ // Branch targets have OtherVT type. def brtarget : Operand; +// Define X86 specific addressing mode. +def addr : ComplexPattern<4, "SelectAddr", []>; +def leaaddr : ComplexPattern<4, "SelectLEAAddr", [add]>; + // Format specifies the encoding used by the instruction. This is part of the // ad-hoc solution used to emit machine instruction encodings by our machine // code emitter. @@ -151,7 +155,6 @@ return (unsigned)N->getValue() == (unsigned char)N->getValue(); }]>; - //===----------------------------------------------------------------------===// // Instruction templates... @@ -297,7 +300,8 @@ "lea{w} {$src|$dst}, {$dst|$src}", []>, OpSize; def LEA32r : I<0x8D, MRMSrcMem, (ops R32:$dst, i32mem:$src), - "lea{l} {$src|$dst}, {$dst|$src}", []>; + "lea{l} {$src|$dst}, {$dst|$src}", + [(set R32:$dst, leaaddr:$src)]>; def REP_MOVSB : I<0xA4, RawFrm, (ops), "{rep;movsb|rep movsb}", []>, @@ -381,11 +385,14 @@ "mov{l} {$src, $dst|$dst, $src}", []>; def MOV8rm : I<0x8A, MRMSrcMem, (ops R8 :$dst, i8mem :$src), - "mov{b} {$src, $dst|$dst, $src}", []>; + "mov{b} {$src, $dst|$dst, $src}", + [(set R8:$dst, (load addr:$src))]>; def MOV16rm : I<0x8B, MRMSrcMem, (ops R16:$dst, i16mem:$src), - "mov{w} {$src, $dst|$dst, $src}", []>, OpSize; + "mov{w} {$src, $dst|$dst, $src}", + [(set R16:$dst, (load addr:$src))]>, OpSize; def MOV32rm : I<0x8B, MRMSrcMem, (ops R32:$dst, i32mem:$src), - "mov{l} {$src, $dst|$dst, $src}", []>; + "mov{l} {$src, $dst|$dst, $src}", + [(set R32:$dst, (load addr:$src))]>; def MOV8mr : I<0x88, MRMDestMem, (ops i8mem :$dst, R8 :$src), "mov{b} {$src, $dst|$dst, $src}", []>; From evan.cheng at apple.com Wed Dec 7 20:14:19 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 7 Dec 2005 20:14:19 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenTarget.cpp CodeGenTarget.h DAGISelEmitter.cpp Message-ID: <200512080214.UAA00684@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenTarget.cpp updated: 1.48 -> 1.49 CodeGenTarget.h updated: 1.22 -> 1.23 DAGISelEmitter.cpp updated: 1.86 -> 1.87 --- Log message: * Added an explicit type field to ComplexPattern. * Renamed MatchingNodes to RootNodes. --- Diffs of the changes: (+12 -9) CodeGenTarget.cpp | 8 +++++--- CodeGenTarget.h | 8 +++++--- DAGISelEmitter.cpp | 5 ++--- 3 files changed, 12 insertions(+), 9 deletions(-) Index: llvm/utils/TableGen/CodeGenTarget.cpp diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.48 llvm/utils/TableGen/CodeGenTarget.cpp:1.49 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.48 Wed Dec 7 20:00:36 2005 +++ llvm/utils/TableGen/CodeGenTarget.cpp Wed Dec 7 20:14:08 2005 @@ -335,7 +335,9 @@ // ComplexPattern implementation // ComplexPattern::ComplexPattern(Record *R) { - NumOperands = R->getValueAsInt("NumOperands"); - SelectFunc = R->getValueAsString("SelectFunc"); - MatchingNodes = R->getValueAsListOfDefs("MatchingNodes"); + Ty = ::getValueType(R->getValueAsDef("Ty")); + NumOperands = R->getValueAsInt("NumOperands"); + SelectFunc = R->getValueAsString("SelectFunc"); + RootNodes = R->getValueAsListOfDefs("RootNodes"); } + Index: llvm/utils/TableGen/CodeGenTarget.h diff -u llvm/utils/TableGen/CodeGenTarget.h:1.22 llvm/utils/TableGen/CodeGenTarget.h:1.23 --- llvm/utils/TableGen/CodeGenTarget.h:1.22 Wed Dec 7 20:00:36 2005 +++ llvm/utils/TableGen/CodeGenTarget.h Wed Dec 7 20:14:08 2005 @@ -160,17 +160,19 @@ /// ComplexPattern - ComplexPattern info, corresponding to the ComplexPattern /// tablegen class in TargetSelectionDAG.td class ComplexPattern { + MVT::ValueType Ty; unsigned NumOperands; std::string SelectFunc; - std::vector MatchingNodes; + std::vector RootNodes; public: ComplexPattern() : NumOperands(0) {}; ComplexPattern(Record *R); + MVT::ValueType getValueType() const { return Ty; } unsigned getNumOperands() const { return NumOperands; } const std::string &getSelectFunc() const { return SelectFunc; } - const std::vector &getMatchingNodes() const { - return MatchingNodes; + const std::vector &getRootNodes() const { + return RootNodes; } }; Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.86 llvm/utils/TableGen/DAGISelEmitter.cpp:1.87 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.86 Wed Dec 7 20:00:36 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed Dec 7 20:14:08 2005 @@ -478,8 +478,7 @@ // Using a VTSDNode or CondCodeSDNode. return MVT::Other; } else if (R->isSubClassOf("ComplexPattern")) { - const CodeGenTarget &T = TP.getDAGISelEmitter().getTargetInfo(); - return T.getPointerType(); + return TP.getDAGISelEmitter().getComplexPattern(R).getValueType(); } else if (R->getName() == "node") { // Placeholder. return MVT::isUnknown; @@ -2256,7 +2255,7 @@ dynamic_cast(Node->getLeafValue())) { PatternsByOpcode[getSDNodeNamed("imm")].push_back(&PatternsToMatch[i]); } else if ((CP = NodeGetComplexPattern(Node, *this))) { - std::vector OpNodes = CP->getMatchingNodes(); + std::vector OpNodes = CP->getRootNodes(); for (unsigned j = 0, e = OpNodes.size(); j != e; j++) { PatternsByOpcode[OpNodes[j]].insert(PatternsByOpcode[OpNodes[j]].begin(), &PatternsToMatch[i]); From evan.cheng at apple.com Wed Dec 7 20:15:18 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 7 Dec 2005 20:15:18 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200512080215.UAA00740@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.149 -> 1.150 --- Log message: Added explicit type field to ComplexPattern. --- Diffs of the changes: (+2 -2) X86InstrInfo.td | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.149 llvm/lib/Target/X86/X86InstrInfo.td:1.150 --- llvm/lib/Target/X86/X86InstrInfo.td:1.149 Wed Dec 7 20:01:35 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Dec 7 20:15:07 2005 @@ -47,8 +47,8 @@ def brtarget : Operand; // Define X86 specific addressing mode. -def addr : ComplexPattern<4, "SelectAddr", []>; -def leaaddr : ComplexPattern<4, "SelectLEAAddr", [add]>; +def addr : ComplexPattern; +def leaaddr : ComplexPattern; // Format specifies the encoding used by the instruction. This is part of the // ad-hoc solution used to emit machine instruction encodings by our machine From evan.cheng at apple.com Wed Dec 7 22:29:00 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 7 Dec 2005 22:29:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200512080429.WAA02144@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.12 -> 1.13 --- Log message: Added support for ComplexPattern. --- Diffs of the changes: (+21 -0) TargetSelectionDAG.td | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.12 llvm/lib/Target/TargetSelectionDAG.td:1.13 --- llvm/lib/Target/TargetSelectionDAG.td:1.12 Sun Dec 4 20:37:26 2005 +++ llvm/lib/Target/TargetSelectionDAG.td Wed Dec 7 22:28:48 2005 @@ -131,6 +131,10 @@ SDTCisInt<0>, SDTCisInt<1> ]>; +def SDTLoad : SDTypeProfile<1, 1, [ // load + SDTCisInt<1> +]>; + //===----------------------------------------------------------------------===// // Selection DAG Node Properties. // @@ -220,6 +224,8 @@ def writeport : SDNode<"ISD::WRITEPORT" , SDTWritePort, [SDNPHasChain]>; +def load : SDNode<"ISD::LOAD" , SDTLoad, [SDNPHasChain]>; + //===----------------------------------------------------------------------===// // Selection DAG Condition Codes @@ -349,3 +355,18 @@ // not needing a full list. class Pat : Pattern; +//===----------------------------------------------------------------------===// +// Complex pattern definitions. +// +// Complex patterns, e.g. X86 addressing mode, requires pattern matching code +// in C++. NumOperands is the number of operands returned by the select function; +// SelectFunc is the name of the function used to pattern match the max. pattern; +// RootNodes are the list of possible root nodes of the sub-dags to match. +// e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>; +// +class ComplexPattern roots = []> { + ValueType Ty = ty; + int NumOperands = numops; + string SelectFunc = fn; + list RootNodes = roots; +} From lattner at cs.uiuc.edu Thu Dec 8 01:13:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Dec 2005 01:13:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200512080713.BAA03198@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.39 -> 1.40 --- Log message: Add another important case we miss --- Diffs of the changes: (+19 -0) README.txt | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.39 llvm/lib/Target/PowerPC/README.txt:1.40 --- llvm/lib/Target/PowerPC/README.txt:1.39 Thu Nov 17 12:26:56 2005 +++ llvm/lib/Target/PowerPC/README.txt Thu Dec 8 01:13:28 2005 @@ -222,3 +222,22 @@ instruction to avoid a copy AFTER the 2-addr instruction. The 2-addr pass currently only commutes to avoid inserting a copy BEFORE the two addr instr. +===-------------------------------------------------------------------------=== + +Compile offsets from allocas: + +int *%test() { + %X = alloca { int, int } + %Y = getelementptr {int,int}* %X, int 0, uint 1 + ret int* %Y +} + +into a single add, not two: + +_test: + addi r2, r1, -8 + addi r3, r2, 4 + blr + +--> important for C++. + From lattner at cs.uiuc.edu Thu Dec 8 02:00:24 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Dec 2005 02:00:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200512080800.CAA04993@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.112 -> 1.113 --- Log message: improve code insertion in two ways: 1. Only forward subst offsets into loads and stores, not into arbitrary things, where it will likely become a load. 2. If the source is a cast from pointer, forward subst the cast as well, allowing us to fold the cast away (improving cases when the cast is from an alloca or global). This hasn't been fully tested, but does appear to further reduce register pressure and improve code. Lets let the testers grind on it a bit. :) --- Diffs of the changes: (+26 -20) SelectionDAGISel.cpp | 46 ++++++++++++++++++++++++++-------------------- 1 files changed, 26 insertions(+), 20 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.112 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.113 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.112 Wed Dec 7 13:48:11 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Dec 8 02:00:12 2005 @@ -1276,6 +1276,13 @@ while (isa(InsertPt)) ++InsertPt; } + // If Ptr is itself a cast, but in some other BB, emit a copy of the cast into + // BB so that there is only one value live across basic blocks (the cast + // operand). + if (CastInst *CI = dyn_cast(Ptr)) + if (CI->getParent() != BB && isa(CI->getOperand(0)->getType())) + Ptr = new CastInst(CI->getOperand(0), CI->getType(), "", InsertPt); + // Add the offset, cast it to the right type. Ptr = BinaryOperator::createAdd(Ptr, PtrOffset, "", InsertPt); Ptr = new CastInst(Ptr, GEPI->getType(), "", InsertPt); @@ -1371,32 +1378,31 @@ // Okay, we have now emitted all of the variable index parts to the BB that // the GEP is defined in. Loop over all of the using instructions, inserting // an "add Ptr, ConstantOffset" into each block that uses it and update the - // instruction to use the newly computed value, making GEPI dead. + // instruction to use the newly computed value, making GEPI dead. When the + // user is a load or store instruction address, we emit the add into the user + // block, otherwise we use a canonical version right next to the gep (these + // won't be foldable as addresses, so we might as well share the computation). + std::map InsertedExprs; while (!GEPI->use_empty()) { Instruction *User = cast(GEPI->use_back()); - - // Handle PHI's specially, as we need to insert code in the predecessor - // blocks for uses, not in the PHI block. - if (PHINode *PN = dyn_cast(User)) { - for (PHINode::op_iterator OI = PN->op_begin(), E = PN->op_end(); - OI != E; OI += 2) { - if (*OI == GEPI) { - BasicBlock *Pred = cast(OI[1]); - *OI = InsertGEPComputeCode(InsertedExprs[Pred], Pred, GEPI, - Ptr, PtrOffset); - } - } - continue; - } - - // Otherwise, insert the code in the User's block so it can be folded into - // any users in that block. - Value *V = InsertGEPComputeCode(InsertedExprs[User->getParent()], + + // If this use is not foldable into the addressing mode, use a version + // emitted in the GEP block. + Value *NewVal; + if (!isa(User) && + (!isa(User) || User->getOperand(0) == GEPI)) { + NewVal = InsertGEPComputeCode(InsertedExprs[DefBB], DefBB, GEPI, + Ptr, PtrOffset); + } else { + // Otherwise, insert the code in the User's block so it can be folded into + // any users in that block. + NewVal = InsertGEPComputeCode(InsertedExprs[User->getParent()], User->getParent(), GEPI, Ptr, PtrOffset); - User->replaceUsesOfWith(GEPI, V); } + User->replaceUsesOfWith(GEPI, NewVal); + } // Finally, the GEP is dead, remove it. GEPI->eraseFromParent(); From alenhar2 at cs.uiuc.edu Thu Dec 8 18:46:02 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 8 Dec 2005 18:46:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrInfo.td Message-ID: <200512090046.SAA29330@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrInfo.td updated: 1.81 -> 1.82 --- Log message: it helps if your conditionals are not reversed --- Diffs of the changes: (+9 -9) AlphaInstrInfo.td | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-) Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.81 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.82 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.81 Tue Dec 6 17:27:39 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Thu Dec 8 18:45:42 2005 @@ -166,22 +166,22 @@ def CMOVLTi : OForm4L< 0x11, 0x44, "cmovlt $RCOND,$L,$RDEST">; //CMOVE if RCOND < zero def CMOVNEi : OForm4L< 0x11, 0x26, "cmovne $RCOND,$L,$RDEST">; //CMOVE if RCOND != zero -let OperandList = (ops GPRC:$RDEST, GPRC:$RTRUE, GPRC:$RFALSE, GPRC:$RCOND) in { -def CMOVLBC : OForm4< 0x11, 0x16, "cmovlbc $RCOND,$RFALSE,$RDEST", +let OperandList = (ops GPRC:$RDEST, GPRC:$RFALSE, GPRC:$RTRUE, GPRC:$RCOND) in { +def CMOVLBC : OForm4< 0x11, 0x16, "cmovlbc $RCOND,$RTRUE,$RDEST", [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVLBS : OForm4< 0x11, 0x14, "cmovlbs $RCOND,$RFALSE,$RDEST", +def CMOVLBS : OForm4< 0x11, 0x14, "cmovlbs $RCOND,$RTRUE,$RDEST", [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVEQ : OForm4< 0x11, 0x24, "cmoveq $RCOND,$RFALSE,$RDEST", +def CMOVEQ : OForm4< 0x11, 0x24, "cmoveq $RCOND,$RTRUE,$RDEST", [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVGE : OForm4< 0x11, 0x46, "cmovge $RCOND,$RFALSE,$RDEST", +def CMOVGE : OForm4< 0x11, 0x46, "cmovge $RCOND,$RTRUE,$RDEST", [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVGT : OForm4< 0x11, 0x66, "cmovgt $RCOND,$RFALSE,$RDEST", +def CMOVGT : OForm4< 0x11, 0x66, "cmovgt $RCOND,$RTRUE,$RDEST", [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVLE : OForm4< 0x11, 0x64, "cmovle $RCOND,$RFALSE,$RDEST", +def CMOVLE : OForm4< 0x11, 0x64, "cmovle $RCOND,$RTRUE,$RDEST", [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVLT : OForm4< 0x11, 0x44, "cmovlt $RCOND,$RFALSE,$RDEST", +def CMOVLT : OForm4< 0x11, 0x44, "cmovlt $RCOND,$RTRUE,$RDEST", [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; -def CMOVNE : OForm4< 0x11, 0x26, "cmovne $RCOND,$RFALSE,$RDEST", +def CMOVNE : OForm4< 0x11, 0x26, "cmovne $RCOND,$RTRUE,$RDEST", [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; } From evan.cheng at apple.com Thu Dec 8 18:48:55 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 8 Dec 2005 18:48:55 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200512090048.SAA00535@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.87 -> 1.88 DAGISelEmitter.h updated: 1.40 -> 1.41 --- Log message: * Make sure complex pattern operands are selected first since their select functions can return false and causing the instruction pattern match to fail. * Code clean up. --- Diffs of the changes: (+83 -66) DAGISelEmitter.cpp | 136 +++++++++++++++++++++++++++++------------------------ DAGISelEmitter.h | 13 ++--- 2 files changed, 83 insertions(+), 66 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.87 llvm/utils/TableGen/DAGISelEmitter.cpp:1.88 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.87 Wed Dec 7 20:14:08 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Dec 8 18:48:42 2005 @@ -1692,7 +1692,10 @@ void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N, const std::string &RootName, std::map &VarMap, - unsigned PatternNo,std::ostream &OS) { + unsigned PatternNo, + std::ostream &OS, + std::string &ChainName, + bool &HasChain, bool &InFlag) { if (N->isLeaf()) { if (IntInit *II = dynamic_cast(N->getLeafValue())) { OS << " if (cast(" << RootName @@ -1724,7 +1727,18 @@ // Emit code to load the child nodes and match their contents recursively. - unsigned OpNo = (unsigned) NodeHasChain(N, *this); + unsigned OpNo = 0; + + if (NodeHasChain(N, *this)) { + OpNo = 1; + if (!HasChain) { + HasChain = true; + OS << " SDOperand " << RootName << "0 = " << RootName + << ".getOperand(0);\n"; + ChainName = RootName + "0"; + } + } + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { OS << " SDOperand " << RootName << OpNo <<" = " << RootName << ".getOperand(" << OpNo << ");\n"; @@ -1736,7 +1750,7 @@ OS << " if (" << RootName << OpNo << ".getOpcode() != " << CInfo.getEnumName() << ") goto P" << PatternNo << "Fail;\n"; EmitMatchForPattern(Child, RootName + utostr(OpNo), VarMap, PatternNo, - OS); + OS, ChainName, HasChain, InFlag); } else { // If this child has a name associated with it, capture it in VarMap. If // we already saw this in the pattern, emit code to verify dagness. @@ -1758,9 +1772,13 @@ // Handle leaves of various types. if (DefInit *DI = dynamic_cast(Child->getLeafValue())) { Record *LeafRec = DI->getDef(); - if (LeafRec->isSubClassOf("RegisterClass") || - LeafRec->isSubClassOf("Register")) { + if (LeafRec->isSubClassOf("RegisterClass")) { // Handle register references. Nothing to do here. + } else if (LeafRec->isSubClassOf("Register")) { + if (!InFlag) { + OS << " SDOperand InFlag = SDOperand(0,0);\n"; + InFlag = true; + } } else if (LeafRec->isSubClassOf("ComplexPattern")) { // Handle complex pattern. Nothing to do here. } else if (LeafRec->isSubClassOf("ValueType")) { @@ -1803,50 +1821,23 @@ return MVT::Other; } - -/// EmitLeadChainForPattern - Emit the flag operands for the DAG that will be -/// built in CodeGenPatternResult. -void DAGISelEmitter::EmitLeadChainForPattern(TreePatternNode *N, - const std::string &RootName, - std::ostream &OS, - bool &HasChain) { - if (!N->isLeaf()) { - bool hc = NodeHasChain(N, *this); - unsigned OpNo = (unsigned) hc; - for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) - EmitLeadChainForPattern(N->getChild(i), RootName + utostr(OpNo), - OS, HasChain); - - if (!HasChain && hc) { - OS << " SDOperand Chain = Select(" - << RootName << ".getOperand(0));\n"; - HasChain = true; - } - } -} - -/// EmitCopyToRegsForPattern - Emit the flag operands for the DAG that will be +/// EmitCopyToRegsForPattern - Emit the flag operands for the DAG that is /// built in CodeGenPatternResult. void DAGISelEmitter::EmitCopyToRegsForPattern(TreePatternNode *N, const std::string &RootName, std::ostream &OS, - bool &HasChain, bool &InFlag) { + bool HasChain) { const CodeGenTarget &T = getTargetInfo(); unsigned OpNo = (unsigned) NodeHasChain(N, *this); for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { TreePatternNode *Child = N->getChild(i); if (!Child->isLeaf()) { - EmitCopyToRegsForPattern(Child, RootName + utostr(OpNo), OS, HasChain, - InFlag); + EmitCopyToRegsForPattern(Child, RootName + utostr(OpNo), OS, HasChain); } else { if (DefInit *DI = dynamic_cast(Child->getLeafValue())) { Record *RR = DI->getDef(); if (RR->isSubClassOf("Register")) { MVT::ValueType RVT = getRegisterValueType(RR, T); - if (!InFlag) { - OS << " SDOperand InFlag = SDOperand(0,0);\n"; - InFlag = true; - } if (HasChain) { OS << " SDOperand " << RootName << "CR" << i << ";\n"; OS << " " << RootName << "CR" << i @@ -1873,11 +1864,11 @@ /// CodeGenPatternResult - Emit the action for a pattern. Now that it has /// matched, we actually have to build a DAG! std::pair DAGISelEmitter:: -CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, +CodeGenPatternResult(TreePatternNode *M, TreePatternNode *N, unsigned &Ctr, + std::string &ChainName, std::map &VariableMap, - unsigned PatternNo, - std::ostream &OS, bool &HasChain, bool InFlag, - bool isRoot) { + unsigned PatternNo, std::ostream &OS, + bool InFlag, bool isRoot) { // This is something selected from the pattern we matched. if (!N->getName().empty()) { assert(!isRoot && "Root of pattern cannot be a leaf!"); @@ -1956,24 +1947,50 @@ Record *Op = N->getOperator(); if (Op->isSubClassOf("Instruction")) { - // Emit all of the operands. - std::vector Ops; + // Determine operand emission order. Complex pattern first. + std::vector > EmitOrder; + std::vector >::iterator OI; for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { TreePatternNode *Child = N->getChild(i); - std::pair NOPair = - CodeGenPatternResult(Child, Ctr, - VariableMap, PatternNo, OS, HasChain, InFlag); - for (unsigned j = 0; j < NOPair.first; j++) - Ops.push_back(NOPair.second + j); + if (i == 0) { + EmitOrder.push_back(std::make_pair(i, Child)); + OI = EmitOrder.begin(); + } else if (NodeIsComplexPattern(Child)) { + OI = EmitOrder.insert(OI, std::make_pair(i, Child)); + } else { + EmitOrder.push_back(std::make_pair(i, Child)); + } + } + + // Emit all of the operands. + std::vector > NumTemps(EmitOrder.size()); + for (unsigned i = 0, e = EmitOrder.size(); i != e; ++i) { + unsigned OpOrder = EmitOrder[i].first; + TreePatternNode *Child = EmitOrder[i].second; + std::pair NumTemp = + CodeGenPatternResult(M, Child, Ctr, ChainName, + VariableMap, PatternNo, OS, InFlag); + NumTemps[OpOrder] = NumTemp; + } + + // List all the operands in the right order. + std::vector Ops; + for (unsigned i = 0, e = NumTemps.size(); i != e; i++) { + for (unsigned j = 0; j < NumTemps[i].first; j++) + Ops.push_back(NumTemps[i].second + j); } CodeGenInstruction &II = Target.getInstruction(Op->getName()); bool HasCtrlDep = II.hasCtrlDep; - unsigned ResNo = Ctr++; + + // Emit all the chain and CopyToReg stuff. + if (HasCtrlDep) + OS << " SDOperand Chain = Select(" << ChainName << ");\n"; + EmitCopyToRegsForPattern(M, "N", OS, HasCtrlDep); const DAGInstruction &Inst = getInstruction(Op); - unsigned NumResults = Inst.getNumResults(); - + unsigned NumResults = Inst.getNumResults(); + unsigned ResNo = Ctr++; if (!isRoot) { OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetNode(" << II.Namespace << "::" << II.TheDef->getName() << ", MVT::" @@ -2041,8 +2058,8 @@ return std::make_pair(1, ResNo); } else if (Op->isSubClassOf("SDNodeXForm")) { assert(N->getNumChildren() == 1 && "node xform should have one child!"); - unsigned OpVal = CodeGenPatternResult(N->getChild(0), Ctr, - VariableMap, PatternNo, OS, HasChain, InFlag) + unsigned OpVal = CodeGenPatternResult(M, N->getChild(0), Ctr, ChainName, + VariableMap, PatternNo, OS, InFlag) .second; unsigned ResNo = Ctr++; @@ -2121,8 +2138,12 @@ << " cost = " << getResultPatternCost(Pattern.second) << "\n"; // Emit the matcher, capturing named arguments in VariableMap. + bool HasChain = false; + bool InFlag = false; std::map VariableMap; - EmitMatchForPattern(Pattern.first, "N", VariableMap, PatternNo, OS); + std::string ChainName; + EmitMatchForPattern(Pattern.first, "N", VariableMap, PatternNo, OS, + ChainName, HasChain, InFlag); // TP - Get *SOME* tree pattern, we don't care which. TreePattern &TP = *PatternFragments.begin()->second; @@ -2159,15 +2180,10 @@ // otherwise we are done. } while (InsertOneTypeCheck(Pat, Pattern.first, *this, "N", PatternNo, OS)); - bool HasChain = false; - EmitLeadChainForPattern(Pattern.first, "N", OS, HasChain); - - bool InFlag = false; - EmitCopyToRegsForPattern(Pattern.first, "N", OS, HasChain, InFlag); - unsigned TmpNo = 0; - CodeGenPatternResult(Pattern.second, - TmpNo, VariableMap, PatternNo, OS, HasChain, InFlag, true /*the root*/); + CodeGenPatternResult(Pattern.first, Pattern.second, + TmpNo, ChainName, VariableMap, PatternNo, OS, InFlag, + true /*the root*/); delete Pat; OS << " }\n P" << PatternNo << "Fail:\n"; Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.40 llvm/utils/TableGen/DAGISelEmitter.h:1.41 --- llvm/utils/TableGen/DAGISelEmitter.h:1.40 Wed Dec 7 20:00:36 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Thu Dec 8 18:48:42 2005 @@ -423,15 +423,16 @@ std::map &InstResults); void EmitMatchForPattern(TreePatternNode *N, const std::string &RootName, std::map &VarMap, - unsigned PatternNo, std::ostream &OS); - void EmitLeadChainForPattern(TreePatternNode *N, const std::string &RootName, - std::ostream &OS, bool &HasChain); + unsigned PatternNo, std::ostream &OS, + std::string &ChainName, + bool &HasChain, bool &InFlag); void EmitCopyToRegsForPattern(TreePatternNode *N, const std::string &RootName, - std::ostream &OS, bool &HasChain, bool &InFlag); + std::ostream &OS, bool HasChain); std::pair - CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, + CodeGenPatternResult(TreePatternNode *M, TreePatternNode *N, unsigned &Ctr, + std::string &ChainName, std::map &VariableMap, - unsigned PatternNo, std::ostream &OS, bool &HasChain, + unsigned PatternNo, std::ostream &OS, bool InFlag, bool isRoot = false); void EmitCodeForPattern(PatternToMatch &Pattern, std::ostream &OS); void EmitInstructionSelector(std::ostream &OS); From evan.cheng at apple.com Fri Dec 9 00:06:20 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 9 Dec 2005 00:06:20 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200512090606.AAA16628@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.88 -> 1.89 DAGISelEmitter.h updated: 1.41 -> 1.42 --- Log message: Prevent folding of instructions which produce chains that have more than 1 real use --- Diffs of the changes: (+9 -4) DAGISelEmitter.cpp | 11 ++++++++--- DAGISelEmitter.h | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.88 llvm/utils/TableGen/DAGISelEmitter.cpp:1.89 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.88 Thu Dec 8 18:48:42 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Dec 9 00:06:08 2005 @@ -1691,11 +1691,12 @@ /// matches, and the SDNode for the result has the RootName specified name. void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N, const std::string &RootName, - std::map &VarMap, + std::map &VarMap, unsigned PatternNo, std::ostream &OS, std::string &ChainName, - bool &HasChain, bool &InFlag) { + bool &HasChain, bool &InFlag, + bool isRoot) { if (N->isLeaf()) { if (IntInit *II = dynamic_cast(N->getLeafValue())) { OS << " if (cast(" << RootName @@ -1731,6 +1732,10 @@ if (NodeHasChain(N, *this)) { OpNo = 1; + if (!isRoot) { + OS << " if (" << RootName << ".hasOneUse()) goto P" + << PatternNo << "Fail;\n"; + } if (!HasChain) { HasChain = true; OS << " SDOperand " << RootName << "0 = " << RootName @@ -2143,7 +2148,7 @@ std::map VariableMap; std::string ChainName; EmitMatchForPattern(Pattern.first, "N", VariableMap, PatternNo, OS, - ChainName, HasChain, InFlag); + ChainName, HasChain, InFlag, true /*the root*/); // TP - Get *SOME* tree pattern, we don't care which. TreePattern &TP = *PatternFragments.begin()->second; Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.41 llvm/utils/TableGen/DAGISelEmitter.h:1.42 --- llvm/utils/TableGen/DAGISelEmitter.h:1.41 Thu Dec 8 18:48:42 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Fri Dec 9 00:06:08 2005 @@ -425,7 +425,7 @@ std::map &VarMap, unsigned PatternNo, std::ostream &OS, std::string &ChainName, - bool &HasChain, bool &InFlag); + bool &HasChain, bool &InFlag, bool isRoot = false); void EmitCopyToRegsForPattern(TreePatternNode *N, const std::string &RootName, std::ostream &OS, bool HasChain); std::pair From alenhar2 at cs.uiuc.edu Fri Dec 9 10:33:14 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Fri, 09 Dec 2005 10:33:14 -0600 Subject: [llvm-commits] Re: llvm-commits Digest, Vol 18, Issue 8 In-Reply-To: <200512081800.jB8I0QKp029443@dcs-maillist.cs.uiuc.edu> References: <200512081800.jB8I0QKp029443@dcs-maillist.cs.uiuc.edu> Message-ID: <1134145994.1411.2.camel@apoc.cs.uiuc.edu> > Message: 1 > Date: Wed, 7 Dec 2005 12:02:16 -0600 > From: "Chris Lattner" > Subject: [llvm-commits] CVS: > llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp > To: llvm-commits at cs.uiuc.edu > Message-ID: <200512071802.MAA03176 at zion.cs.uiuc.edu> > Changes in directory llvm/lib/CodeGen/SelectionDAG: > > DAGCombiner.cpp updated: 1.63 -> 1.64 > --- > Log message: > > Only transform (sext (truncate x)) -> (sextinreg x) if before legalize or > if the target supports the resultant sextinreg I think it is this change that breaks thing. This leads to i32 = sign_extend_inreg hitting promoteOp, which cannot deal with it. reduction for alpha: ;ModuleID = 'bugpoint-reduced-simplified.bc' target endian = little target pointersize = 64 %id.0__ = external global ushort implementation ; Functions: fastcc void %dxi_send() { entry: %tmp.233 = load ushort* %id.0__ %tmp.234 = cast ushort %tmp.233 to int %tmp.235 = load short* null %tmp.236 = cast short %tmp.235 to ushort %tmp.244 = cast ushort %tmp.236 to int %tmp.245 = shl int %tmp.244, ubyte 8 %tmp.247 = and int %tmp.245, 65280 %tmp.248 = or int 0, %tmp.247 %tmp.249 = cast int %tmp.248 to short %tmp.250 = cast short %tmp.249 to int %tmp.251 = seteq int %tmp.234, %tmp.250 br bool %tmp.251, label %endif.20, label %then.20 then.20: ; preds = %entry ret void endif.20: ; preds = %entry call void %llvm.memcpy( sbyte* null, sbyte* null, ulong 8, uint 1 ) unreachable } declare void %llvm.memcpy(sbyte*, sbyte*, ulong, uint) > > --- > Diffs of the changes: (+3 -1) > > DAGCombiner.cpp | 4 +++- > 1 files changed, 3 insertions(+), 1 deletion(-) > > > Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp > diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.63 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.64 > --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.63 Wed Dec 7 01:11:03 2005 > +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Dec 7 12:02:05 2005 > @@ -1547,7 +1547,9 @@ > if (N0.getOpcode() == ISD::SEXTLOAD && VT == N0.getValueType()) > return N0; > // fold (sext (truncate x)) -> (sextinreg x) iff x size == sext size. > - if (N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getValueType() == VT) > + if (N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getValueType() == VT&& > + (!AfterLegalize || > + TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, N0.getValueType()))) > return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), > DAG.getValueType(N0.getValueType())); > // fold (sext (load x)) -> (sextload x) From lattner at cs.uiuc.edu Fri Dec 9 11:33:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Dec 2005 11:33:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200512091733.LAA32484@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.224 -> 1.225 --- Log message: Teach legalize how to promote sext_inreg to fix a problem Andrew pointed out to me. --- Diffs of the changes: (+5 -0) LegalizeDAG.cpp | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.224 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.225 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.224 Wed Dec 7 13:48:11 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Dec 9 11:32:47 2005 @@ -2404,6 +2404,11 @@ } break; + case ISD::SIGN_EXTEND_INREG: + Result = PromoteOp(Node->getOperand(0)); + Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Result, + Node->getOperand(1)); + break; case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: switch (getTypeAction(Node->getOperand(0).getValueType())) { From sabre at nondot.org Fri Dec 9 11:33:11 2005 From: sabre at nondot.org (Chris Lattner) Date: Fri, 9 Dec 2005 11:33:11 -0600 (CST) Subject: [llvm-commits] Re: llvm-commits Digest, Vol 18, Issue 8 In-Reply-To: <1134145994.1411.2.camel@apoc.cs.uiuc.edu> References: <200512081800.jB8I0QKp029443@dcs-maillist.cs.uiuc.edu> <1134145994.1411.2.camel@apoc.cs.uiuc.edu> Message-ID: > I think it is this change that breaks thing. This leads to i32 = > sign_extend_inreg hitting promoteOp, which cannot deal with it. Fixed, thanks. -Chris >> Message: 1 >> Date: Wed, 7 Dec 2005 12:02:16 -0600 >> From: "Chris Lattner" >> Subject: [llvm-commits] CVS: >> llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp >> To: llvm-commits at cs.uiuc.edu >> Message-ID: <200512071802.MAA03176 at zion.cs.uiuc.edu> > >> Changes in directory llvm/lib/CodeGen/SelectionDAG: >> >> DAGCombiner.cpp updated: 1.63 -> 1.64 >> --- >> Log message: >> >> Only transform (sext (truncate x)) -> (sextinreg x) if before legalize or >> if the target supports the resultant sextinreg > > > reduction for alpha: > > ;ModuleID = 'bugpoint-reduced-simplified.bc' > target endian = little > target pointersize = 64 > %id.0__ = external global ushort > > implementation ; Functions: > > fastcc void %dxi_send() { > entry: > %tmp.233 = load ushort* %id.0__ > %tmp.234 = cast ushort %tmp.233 to int > %tmp.235 = load short* null > %tmp.236 = cast short %tmp.235 to ushort > %tmp.244 = cast ushort %tmp.236 to int > %tmp.245 = shl int %tmp.244, ubyte 8 > %tmp.247 = and int %tmp.245, 65280 > %tmp.248 = or int 0, %tmp.247 > %tmp.249 = cast int %tmp.248 to short > %tmp.250 = cast short %tmp.249 to int > %tmp.251 = seteq int %tmp.234, %tmp.250 > br bool %tmp.251, label %endif.20, label %then.20 > > then.20: ; preds = %entry > ret void > > endif.20: ; preds = %entry > call void %llvm.memcpy( sbyte* null, sbyte* null, ulong 8, uint > 1 ) > unreachable > } > > declare void %llvm.memcpy(sbyte*, sbyte*, ulong, uint) > > >> >> --- >> Diffs of the changes: (+3 -1) >> >> DAGCombiner.cpp | 4 +++- >> 1 files changed, 3 insertions(+), 1 deletion(-) >> >> >> Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp >> diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.63 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.64 >> --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.63 Wed Dec 7 01:11:03 2005 >> +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Dec 7 12:02:05 2005 >> @@ -1547,7 +1547,9 @@ >> if (N0.getOpcode() == ISD::SEXTLOAD && VT == N0.getValueType()) >> return N0; >> // fold (sext (truncate x)) -> (sextinreg x) iff x size == sext size. >> - if (N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getValueType() == VT) >> + if (N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getValueType() == VT&& >> + (!AfterLegalize || >> + TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, N0.getValueType()))) >> return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), >> DAG.getValueType(N0.getValueType())); >> // fold (sext (load x)) -> (sextload x) > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -Chris -- http://nondot.org/sabre/ http://llvm.org/ From lattner at cs.uiuc.edu Fri Dec 9 12:24:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Dec 2005 12:24:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200512091824.MAA00540@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.122 -> 1.123 --- Log message: Teach the PPC backend about the ctor and dtor list when not using __main and linking the entire program into one bc file. --- Diffs of the changes: (+34 -0) PPCAsmPrinter.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 files changed, 34 insertions(+) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.122 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.123 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.122 Wed Nov 30 12:54:35 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Fri Dec 9 12:24:29 2005 @@ -202,6 +202,8 @@ virtual const char *getPassName() const { return "Darwin PPC Assembly Printer"; } + + void EmitXXStructorList(Constant *List); bool runOnMachineFunction(MachineFunction &F); bool doInitialization(Module &M); @@ -412,6 +414,21 @@ return false; } +/// EmitXXStructorList - Emit the ctor or dtor list. On darwin, this just +/// prints out the function pointers. +void DarwinAsmPrinter::EmitXXStructorList(Constant *List) { + // Should be an array of '{ int, void ()* }' structs. The first value is the + // init priority, which we ignore. + if (!isa(List)) return; + ConstantArray *InitList = cast(List); + for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) + if (ConstantStruct *CS = dyn_cast(InitList->getOperand(i))){ + if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. + // Emit the function pointer. + EmitGlobalConstant(CS->getOperand(1)); + } +} + bool DarwinAsmPrinter::doFinalization(Module &M) { const TargetData &TD = TM.getTargetData(); @@ -419,6 +436,23 @@ for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (I->hasInitializer()) { // External global require no code + // Check to see if this is a special global used by LLVM. + if (I->hasAppendingLinkage()) { + if (I->getName() == "llvm.used") + continue; // No need to emit this at all. + if (I->getName() == "llvm.global_ctors") { + SwitchSection(".mod_init_func", 0); + EmitAlignment(2, 0); + EmitXXStructorList(I->getInitializer()); + continue; + } else if (I->getName() == "llvm.global_dtors") { + SwitchSection(".mod_term_func", 0); + EmitAlignment(2, 0); + EmitXXStructorList(I->getInitializer()); + continue; + } + } + O << '\n'; std::string name = Mang->getValueName(I); Constant *C = I->getInitializer(); From lattner at cs.uiuc.edu Fri Dec 9 13:29:01 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Dec 2005 13:29:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200512091929.NAA01328@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.30 -> 1.31 --- Log message: Avoid emitting two tabs when switching to a named section --- Diffs of the changes: (+2 -2) AsmPrinter.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.30 llvm/lib/CodeGen/AsmPrinter.cpp:1.31 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.30 Tue Dec 6 00:18:55 2005 +++ llvm/lib/CodeGen/AsmPrinter.cpp Fri Dec 9 13:28:49 2005 @@ -30,12 +30,12 @@ if (GV && GV->hasSection()) NS = SwitchToSectionDirective + GV->getSection(); else - NS = NewSection; + NS = std::string("\t")+NewSection; if (CurrentSection != NS) { CurrentSection = NS; if (!CurrentSection.empty()) - O << "\t" << CurrentSection << "\n"; + O << CurrentSection << '\n'; } } From evan.cheng at apple.com Fri Dec 9 16:45:47 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 9 Dec 2005 16:45:47 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200512092245.QAA02662@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.89 -> 1.90 DAGISelEmitter.h updated: 1.42 -> 1.43 --- Log message: * Do not allow nodes which produce chain results (e.g. loads) to be folded if it has more than one real use (non-chain uses). * Record folded chain producing node in CodeGenMap. * Do not fold a chain producing node if it has already been selected as an operand of a chain use. --- Diffs of the changes: (+421 -427) DAGISelEmitter.cpp | 835 ++++++++++++++++++++++++++--------------------------- DAGISelEmitter.h | 13 2 files changed, 421 insertions(+), 427 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.89 llvm/utils/TableGen/DAGISelEmitter.cpp:1.90 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.89 Fri Dec 9 00:06:08 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Dec 9 16:45:35 2005 @@ -1686,446 +1686,458 @@ } }; -/// 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. -void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N, - const std::string &RootName, - std::map &VarMap, - unsigned PatternNo, - std::ostream &OS, - std::string &ChainName, - bool &HasChain, bool &InFlag, - bool isRoot) { - if (N->isLeaf()) { - if (IntInit *II = dynamic_cast(N->getLeafValue())) { - OS << " if (cast(" << RootName - << ")->getSignExtended() != " << II->getValue() << ")\n" - << " goto P" << PatternNo << "Fail;\n"; - return; - } else if (!NodeIsComplexPattern(N)) { - assert(0 && "Cannot match this as a leaf value!"); - abort(); +/// getRegisterValueType - Look up and return the first ValueType of specified +/// RegisterClass record +static MVT::ValueType getRegisterValueType(Record *R, const CodeGenTarget &T) { + if (const CodeGenRegisterClass *RC = T.getRegisterClassForRegister(R)) + return RC->getValueTypeNum(0); + return MVT::Other; +} + + +/// RemoveAllTypes - A quick recursive walk over a pattern which removes all +/// type information from it. +static void RemoveAllTypes(TreePatternNode *N) { + N->setType(MVT::isUnknown); + if (!N->isLeaf()) + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) + RemoveAllTypes(N->getChild(i)); +} + +Record *DAGISelEmitter::getSDNodeNamed(const std::string &Name) const { + Record *N = Records.getDef(Name); + assert(N && N->isSubClassOf("SDNode") && "Bad argument"); + return N; +} + +class PatternCodeEmitter { +private: + DAGISelEmitter &ISE; + + // LHS of the pattern being matched + TreePatternNode *LHS; + unsigned PatternNo; + std::ostream &OS; + // Node to name mapping + std::map VariableMap; + // Name of the inner most node which produces a chain. + std::string InnerChain; + // Names of all the folded nodes which produce chains. + std::vector FoldedChains; + bool InFlag; + unsigned TmpNo; + +public: + PatternCodeEmitter(DAGISelEmitter &ise, TreePatternNode *lhs, + unsigned PatNum, std::ostream &os) : + ISE(ise), LHS(lhs), PatternNo(PatNum), OS(os), + InFlag(false), TmpNo(0) {}; + + /// EmitMatchCode - 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. + void EmitMatchCode(TreePatternNode *N, const std::string &RootName, + bool isRoot = false) { + if (N->isLeaf()) { + if (IntInit *II = dynamic_cast(N->getLeafValue())) { + OS << " if (cast(" << RootName + << ")->getSignExtended() != " << II->getValue() << ")\n" + << " goto P" << PatternNo << "Fail;\n"; + return; + } else if (!NodeIsComplexPattern(N)) { + assert(0 && "Cannot match this as a leaf value!"); + abort(); + } } - } - // If this node has a name associated with it, capture it in VarMap. If - // we already saw this in the pattern, emit code to verify dagness. - if (!N->getName().empty()) { - std::string &VarMapEntry = VarMap[N->getName()]; - if (VarMapEntry.empty()) { - VarMapEntry = RootName; - } else { - // If we get here, this is a second reference to a specific name. Since - // we already have checked that the first reference is valid, we don't - // have to recursively match it, just check that it's the same as the - // previously named thing. - OS << " if (" << VarMapEntry << " != " << RootName - << ") goto P" << PatternNo << "Fail;\n"; - return; + // If this node has a name associated with it, capture it in VariableMap. If + // we already saw this in the pattern, emit code to verify dagness. + if (!N->getName().empty()) { + std::string &VarMapEntry = VariableMap[N->getName()]; + if (VarMapEntry.empty()) { + VarMapEntry = RootName; + } else { + // If we get here, this is a second reference to a specific name. Since + // we already have checked that the first reference is valid, we don't + // have to recursively match it, just check that it's the same as the + // previously named thing. + OS << " if (" << VarMapEntry << " != " << RootName + << ") goto P" << PatternNo << "Fail;\n"; + return; + } } - } - // Emit code to load the child nodes and match their contents recursively. - unsigned OpNo = 0; - - if (NodeHasChain(N, *this)) { - OpNo = 1; - if (!isRoot) { - OS << " if (" << RootName << ".hasOneUse()) goto P" - << PatternNo << "Fail;\n"; - } - if (!HasChain) { - HasChain = true; - OS << " SDOperand " << RootName << "0 = " << RootName - << ".getOperand(0);\n"; - ChainName = RootName + "0"; + // Emit code to load the child nodes and match their contents recursively. + unsigned OpNo = 0; + if (NodeHasChain(N, ISE)) { + OpNo = 1; + if (!isRoot) { + OS << " if (!" << RootName << ".hasOneUse()) goto P" + << PatternNo << "Fail; // Multiple uses of actual result?\n"; + OS << " if (CodeGenMap.count(" << RootName + << ".getValue(1))) goto P" + << PatternNo << "Fail; // Already selected for a chain use?\n"; + } + if (InnerChain.empty()) { + OS << " SDOperand " << RootName << "0 = " << RootName + << ".getOperand(0);\n"; + InnerChain = RootName + "0"; + } } - } - for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { - OS << " SDOperand " << RootName << OpNo <<" = " << RootName - << ".getOperand(" << OpNo << ");\n"; - TreePatternNode *Child = N->getChild(i); + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { + OS << " SDOperand " << RootName << OpNo <<" = " << RootName + << ".getOperand(" << OpNo << ");\n"; + TreePatternNode *Child = N->getChild(i); - if (!Child->isLeaf()) { - // If it's not a leaf, recursively match. - const SDNodeInfo &CInfo = getSDNodeInfo(Child->getOperator()); - OS << " if (" << RootName << OpNo << ".getOpcode() != " - << CInfo.getEnumName() << ") goto P" << PatternNo << "Fail;\n"; - EmitMatchForPattern(Child, RootName + utostr(OpNo), VarMap, PatternNo, - OS, ChainName, HasChain, InFlag); - } else { - // If this child has a name associated with it, capture it in VarMap. If - // we already saw this in the pattern, emit code to verify dagness. - if (!Child->getName().empty()) { - std::string &VarMapEntry = VarMap[Child->getName()]; - if (VarMapEntry.empty()) { - VarMapEntry = RootName + utostr(OpNo); - } else { - // If we get here, this is a second reference to a specific name. Since - // we already have checked that the first reference is valid, we don't - // have to recursively match it, just check that it's the same as the - // previously named thing. - OS << " if (" << VarMapEntry << " != " << RootName << OpNo - << ") goto P" << PatternNo << "Fail;\n"; - continue; + if (!Child->isLeaf()) { + // If it's not a leaf, recursively match. + const SDNodeInfo &CInfo = ISE.getSDNodeInfo(Child->getOperator()); + OS << " if (" << RootName << OpNo << ".getOpcode() != " + << CInfo.getEnumName() << ") goto P" << PatternNo << "Fail;\n"; + EmitMatchCode(Child, RootName + utostr(OpNo)); + if (NodeHasChain(Child, ISE)) + FoldedChains.push_back(RootName + utostr(OpNo)); + } else { + // If this child has a name associated with it, capture it in VarMap. If + // we already saw this in the pattern, emit code to verify dagness. + if (!Child->getName().empty()) { + std::string &VarMapEntry = VariableMap[Child->getName()]; + if (VarMapEntry.empty()) { + VarMapEntry = RootName + utostr(OpNo); + } else { + // If we get here, this is a second reference to a specific name. Since + // we already have checked that the first reference is valid, we don't + // have to recursively match it, just check that it's the same as the + // previously named thing. + OS << " if (" << VarMapEntry << " != " << RootName << OpNo + << ") goto P" << PatternNo << "Fail;\n"; + continue; + } } - } - // Handle leaves of various types. - if (DefInit *DI = dynamic_cast(Child->getLeafValue())) { - Record *LeafRec = DI->getDef(); - if (LeafRec->isSubClassOf("RegisterClass")) { - // Handle register references. Nothing to do here. - } else if (LeafRec->isSubClassOf("Register")) { - if (!InFlag) { - OS << " SDOperand InFlag = SDOperand(0,0);\n"; - InFlag = true; + // Handle leaves of various types. + if (DefInit *DI = dynamic_cast(Child->getLeafValue())) { + Record *LeafRec = DI->getDef(); + if (LeafRec->isSubClassOf("RegisterClass")) { + // Handle register references. Nothing to do here. + } else if (LeafRec->isSubClassOf("Register")) { + if (!InFlag) { + OS << " SDOperand InFlag = SDOperand(0,0);\n"; + InFlag = true; + } + } else if (LeafRec->isSubClassOf("ComplexPattern")) { + // Handle complex pattern. Nothing to do here. + } else if (LeafRec->isSubClassOf("ValueType")) { + // Make sure this is the specified value type. + OS << " if (cast(" << RootName << OpNo << ")->getVT() != " + << "MVT::" << LeafRec->getName() << ") goto P" << PatternNo + << "Fail;\n"; + } else if (LeafRec->isSubClassOf("CondCode")) { + // Make sure this is the specified cond code. + OS << " if (cast(" << RootName << OpNo + << ")->get() != " << "ISD::" << LeafRec->getName() + << ") goto P" << PatternNo << "Fail;\n"; + } else { + Child->dump(); + assert(0 && "Unknown leaf type!"); } - } else if (LeafRec->isSubClassOf("ComplexPattern")) { - // Handle complex pattern. Nothing to do here. - } else if (LeafRec->isSubClassOf("ValueType")) { - // Make sure this is the specified value type. - OS << " if (cast(" << RootName << OpNo << ")->getVT() != " - << "MVT::" << LeafRec->getName() << ") goto P" << PatternNo - << "Fail;\n"; - } else if (LeafRec->isSubClassOf("CondCode")) { - // Make sure this is the specified cond code. - OS << " if (cast(" << RootName << OpNo - << ")->get() != " << "ISD::" << LeafRec->getName() - << ") goto P" << PatternNo << "Fail;\n"; + } else if (IntInit *II = dynamic_cast(Child->getLeafValue())) { + OS << " if (!isa(" << RootName << OpNo << ") ||\n" + << " cast(" << RootName << OpNo + << ")->getSignExtended() != " << II->getValue() << ")\n" + << " goto P" << PatternNo << "Fail;\n"; } else { Child->dump(); assert(0 && "Unknown leaf type!"); } - } else if (IntInit *II = dynamic_cast(Child->getLeafValue())) { - OS << " if (!isa(" << RootName << OpNo << ") ||\n" - << " cast(" << RootName << OpNo - << ")->getSignExtended() != " << II->getValue() << ")\n" - << " goto P" << PatternNo << "Fail;\n"; - } else { - Child->dump(); - assert(0 && "Unknown leaf type!"); } } - } - - // If there is a node predicate for this, emit the call. - if (!N->getPredicateFn().empty()) - OS << " if (!" << N->getPredicateFn() << "(" << RootName - << ".Val)) goto P" << PatternNo << "Fail;\n"; -} -/// getRegisterValueType - Look up and return the first ValueType of specified -/// RegisterClass record -static MVT::ValueType getRegisterValueType(Record *R, const CodeGenTarget &T) { - if (const CodeGenRegisterClass *RC = T.getRegisterClassForRegister(R)) - return RC->getValueTypeNum(0); - return MVT::Other; -} + // If there is a node predicate for this, emit the call. + if (!N->getPredicateFn().empty()) + OS << " if (!" << N->getPredicateFn() << "(" << RootName + << ".Val)) goto P" << PatternNo << "Fail;\n"; + } + + /// EmitResultCode - Emit the action for a pattern. Now that it has matched + /// we actually have to build a DAG! + std::pair + EmitResultCode(TreePatternNode *N, bool isRoot = false) { + // This is something selected from the pattern we matched. + if (!N->getName().empty()) { + assert(!isRoot && "Root of pattern cannot be a leaf!"); + 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. + return std::make_pair(1, atoi(Val.c_str()+3)); + } -/// EmitCopyToRegsForPattern - Emit the flag operands for the DAG that is -/// built in CodeGenPatternResult. -void DAGISelEmitter::EmitCopyToRegsForPattern(TreePatternNode *N, - const std::string &RootName, - std::ostream &OS, - bool HasChain) { - const CodeGenTarget &T = getTargetInfo(); - unsigned OpNo = (unsigned) NodeHasChain(N, *this); - for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { - TreePatternNode *Child = N->getChild(i); - if (!Child->isLeaf()) { - EmitCopyToRegsForPattern(Child, RootName + utostr(OpNo), OS, HasChain); - } else { - if (DefInit *DI = dynamic_cast(Child->getLeafValue())) { - Record *RR = DI->getDef(); - if (RR->isSubClassOf("Register")) { - MVT::ValueType RVT = getRegisterValueType(RR, T); - if (HasChain) { - OS << " SDOperand " << RootName << "CR" << i << ";\n"; - OS << " " << RootName << "CR" << i - << " = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(" - << getQualifiedName(RR) << ", MVT::" << getEnumName(RVT) << ")" - << ", Select(" << RootName << OpNo << "), InFlag);\n"; - OS << " Chain = " << RootName << "CR" << i - << ".getValue(0);\n"; - OS << " InFlag = " << RootName << "CR" << i - << ".getValue(1);\n"; - } else { - OS << " InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode()" - << ", CurDAG->getRegister(" << getQualifiedName(RR) - << ", MVT::" << getEnumName(RVT) << ")" - << ", Select(" << RootName << OpNo - << "), InFlag).getValue(1);\n"; - } + const ComplexPattern *CP; + unsigned ResNo = TmpNo++; + unsigned NumRes = 1; + 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 if (!N->isLeaf() && N->getOperator()->getName() == "tglobaladdr") { + OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; + } else if (N->isLeaf() && (CP = NodeGetComplexPattern(N, ISE))) { + std::string Fn = CP->getSelectFunc(); + NumRes = CP->getNumOperands(); + OS << " SDOperand "; + for (unsigned i = 0; i < NumRes; i++) { + if (i != 0) OS << ", "; + OS << "Tmp" << i + ResNo; + } + OS << ";\n"; + OS << " if (!" << Fn << "(" << Val; + for (unsigned i = 0; i < NumRes; i++) + OS << " , Tmp" << i + ResNo; + OS << ")) goto P" << PatternNo << "Fail;\n"; + TmpNo = ResNo + NumRes; + } else { + OS << " SDOperand Tmp" << ResNo << " = Select(" << Val << ");\n"; } - } - } -} - -/// CodeGenPatternResult - Emit the action for a pattern. Now that it has -/// matched, we actually have to build a DAG! -std::pair DAGISelEmitter:: -CodeGenPatternResult(TreePatternNode *M, TreePatternNode *N, unsigned &Ctr, - std::string &ChainName, - std::map &VariableMap, - unsigned PatternNo, std::ostream &OS, - bool InFlag, bool isRoot) { - // This is something selected from the pattern we matched. - if (!N->getName().empty()) { - assert(!isRoot && "Root of pattern cannot be a leaf!"); - 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. - return std::make_pair(1, atoi(Val.c_str()+3)); - } - - const ComplexPattern *CP; - unsigned ResNo = Ctr++; - unsigned NumRes = 1; - 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 if (!N->isLeaf() && N->getOperator()->getName() == "tglobaladdr") { - OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; - } else if (N->isLeaf() && (CP = NodeGetComplexPattern(N, *this))) { - std::string Fn = CP->getSelectFunc(); - NumRes = CP->getNumOperands(); - OS << " SDOperand "; - for (unsigned i = 0; i < NumRes; i++) { - if (i != 0) OS << ", "; - OS << "Tmp" << i + ResNo; - } - OS << ";\n"; - OS << " if (!" << Fn << "(" << Val; - for (unsigned i = 0; i < NumRes; i++) - OS << " , Tmp" << i + ResNo; - OS << ")) goto P" << PatternNo << "Fail;\n"; - Ctr = ResNo + NumRes; - } else { - 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 std::make_pair(NumRes, ResNo); - } - - if (N->isLeaf()) { - // If this is an explicit register reference, handle it. - if (DefInit *DI = dynamic_cast(N->getLeafValue())) { - unsigned ResNo = Ctr++; - if (DI->getDef()->isSubClassOf("Register")) { - OS << " SDOperand Tmp" << ResNo << " = CurDAG->getRegister(" - << getQualifiedName(DI->getDef()) << ", MVT::" + // 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 std::make_pair(NumRes, ResNo); + } + + if (N->isLeaf()) { + // If this is an explicit register reference, handle it. + if (DefInit *DI = dynamic_cast(N->getLeafValue())) { + unsigned ResNo = TmpNo++; + if (DI->getDef()->isSubClassOf("Register")) { + OS << " SDOperand Tmp" << ResNo << " = CurDAG->getRegister(" + << ISE.getQualifiedName(DI->getDef()) << ", MVT::" + << getEnumName(N->getType()) + << ");\n"; + return std::make_pair(1, ResNo); + } + } else if (IntInit *II = dynamic_cast(N->getLeafValue())) { + unsigned ResNo = TmpNo++; + OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetConstant(" + << II->getValue() << ", MVT::" << getEnumName(N->getType()) << ");\n"; return std::make_pair(1, ResNo); } - } else if (IntInit *II = dynamic_cast(N->getLeafValue())) { - unsigned ResNo = Ctr++; - OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetConstant(" - << II->getValue() << ", MVT::" - << getEnumName(N->getType()) - << ");\n"; - return std::make_pair(1, ResNo); - } - N->dump(); - assert(0 && "Unknown leaf type!"); - return std::make_pair(1, ~0U); - } + N->dump(); + assert(0 && "Unknown leaf type!"); + return std::make_pair(1, ~0U); + } + + Record *Op = N->getOperator(); + if (Op->isSubClassOf("Instruction")) { + // Determine operand emission order. Complex pattern first. + std::vector > EmitOrder; + std::vector >::iterator OI; + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { + TreePatternNode *Child = N->getChild(i); + if (i == 0) { + EmitOrder.push_back(std::make_pair(i, Child)); + OI = EmitOrder.begin(); + } else if (NodeIsComplexPattern(Child)) { + OI = EmitOrder.insert(OI, std::make_pair(i, Child)); + } else { + EmitOrder.push_back(std::make_pair(i, Child)); + } + } - Record *Op = N->getOperator(); - if (Op->isSubClassOf("Instruction")) { - // Determine operand emission order. Complex pattern first. - std::vector > EmitOrder; - std::vector >::iterator OI; - for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { - TreePatternNode *Child = N->getChild(i); - if (i == 0) { - EmitOrder.push_back(std::make_pair(i, Child)); - OI = EmitOrder.begin(); - } else if (NodeIsComplexPattern(Child)) { - OI = EmitOrder.insert(OI, std::make_pair(i, Child)); + // Emit all of the operands. + std::vector > NumTemps(EmitOrder.size()); + for (unsigned i = 0, e = EmitOrder.size(); i != e; ++i) { + unsigned OpOrder = EmitOrder[i].first; + TreePatternNode *Child = EmitOrder[i].second; + std::pair NumTemp = EmitResultCode(Child); + NumTemps[OpOrder] = NumTemp; + } + + // List all the operands in the right order. + std::vector Ops; + for (unsigned i = 0, e = NumTemps.size(); i != e; i++) { + for (unsigned j = 0; j < NumTemps[i].first; j++) + Ops.push_back(NumTemps[i].second + j); + } + + CodeGenInstruction &II = + ISE.getTargetInfo().getInstruction(Op->getName()); + + // Emit all the chain and CopyToReg stuff. + if (II.hasCtrlDep) + OS << " SDOperand Chain = Select(" << InnerChain << ");\n"; + EmitCopyToRegs(LHS, "N", II.hasCtrlDep); + + const DAGInstruction &Inst = ISE.getInstruction(Op); + unsigned NumResults = Inst.getNumResults(); + unsigned ResNo = TmpNo++; + if (!isRoot) { + OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetNode(" + << II.Namespace << "::" << II.TheDef->getName() << ", MVT::" + << getEnumName(N->getType()); + unsigned LastOp = 0; + for (unsigned i = 0, e = Ops.size(); i != e; ++i) { + LastOp = Ops[i]; + OS << ", Tmp" << LastOp; + } + OS << ");\n"; + if (II.hasCtrlDep) { + // Must have at least one result + OS << " Chain = Tmp" << LastOp << ".getValue(" + << NumResults << ");\n"; + } + } else if (II.hasCtrlDep) { + OS << " SDOperand Result = "; + OS << "CurDAG->getTargetNode(" + << II.Namespace << "::" << II.TheDef->getName(); + if (NumResults > 0) + OS << ", MVT::" << getEnumName(N->getType()); // TODO: multiple results? + OS << ", MVT::Other"; + for (unsigned i = 0, e = Ops.size(); i != e; ++i) + OS << ", Tmp" << Ops[i]; + OS << ", Chain"; + if (InFlag) + OS << ", InFlag"; + OS << ");\n"; + if (NumResults != 0) { + OS << " CodeGenMap[N] = Result;\n"; + } + OS << " Chain "; + if (NodeHasChain(LHS, ISE)) + OS << "= CodeGenMap[N.getValue(1)] "; + for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) + OS << "= CodeGenMap[" << FoldedChains[j] << ".getValue(1)] "; + OS << "= Result.getValue(1);\n"; + if (NumResults == 0) + OS << " return Chain;\n"; + else + OS << " return (N.ResNo) ? Chain : Result.getValue(0);\n"; } else { - EmitOrder.push_back(std::make_pair(i, Child)); + // If this instruction is the root, and if there is only one use of it, + // use SelectNodeTo instead of getTargetNode to avoid an allocation. + OS << " if (N.Val->hasOneUse()) {\n"; + OS << " return CurDAG->SelectNodeTo(N.Val, " + << II.Namespace << "::" << II.TheDef->getName() << ", MVT::" + << getEnumName(N->getType()); + for (unsigned i = 0, e = Ops.size(); i != e; ++i) + OS << ", Tmp" << Ops[i]; + if (InFlag) + OS << ", InFlag"; + OS << ");\n"; + OS << " } else {\n"; + OS << " return CodeGenMap[N] = CurDAG->getTargetNode(" + << II.Namespace << "::" << II.TheDef->getName() << ", MVT::" + << getEnumName(N->getType()); + for (unsigned i = 0, e = Ops.size(); i != e; ++i) + OS << ", Tmp" << Ops[i]; + if (InFlag) + OS << ", InFlag"; + OS << ");\n"; + OS << " }\n"; } - } - - // Emit all of the operands. - std::vector > NumTemps(EmitOrder.size()); - for (unsigned i = 0, e = EmitOrder.size(); i != e; ++i) { - unsigned OpOrder = EmitOrder[i].first; - TreePatternNode *Child = EmitOrder[i].second; - std::pair NumTemp = - CodeGenPatternResult(M, Child, Ctr, ChainName, - VariableMap, PatternNo, OS, InFlag); - NumTemps[OpOrder] = NumTemp; - } - - // List all the operands in the right order. - std::vector Ops; - for (unsigned i = 0, e = NumTemps.size(); i != e; i++) { - for (unsigned j = 0; j < NumTemps[i].first; j++) - Ops.push_back(NumTemps[i].second + j); - } - - CodeGenInstruction &II = Target.getInstruction(Op->getName()); - bool HasCtrlDep = II.hasCtrlDep; - - // Emit all the chain and CopyToReg stuff. - if (HasCtrlDep) - OS << " SDOperand Chain = Select(" << ChainName << ");\n"; - EmitCopyToRegsForPattern(M, "N", OS, HasCtrlDep); - - const DAGInstruction &Inst = getInstruction(Op); - unsigned NumResults = Inst.getNumResults(); - unsigned ResNo = Ctr++; - if (!isRoot) { - OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetNode(" - << II.Namespace << "::" << II.TheDef->getName() << ", MVT::" - << getEnumName(N->getType()); - unsigned LastOp = 0; - for (unsigned i = 0, e = Ops.size(); i != e; ++i) { - LastOp = Ops[i]; - OS << ", Tmp" << LastOp; - } - OS << ");\n"; - if (HasCtrlDep) { - // Must have at least one result - OS << " Chain = Tmp" << LastOp << ".getValue(" - << NumResults << ");\n"; + return std::make_pair(1, ResNo); + } else if (Op->isSubClassOf("SDNodeXForm")) { + assert(N->getNumChildren() == 1 && "node xform should have one child!"); + unsigned OpVal = EmitResultCode(N->getChild(0)) + .second; + + unsigned ResNo = TmpNo++; + OS << " SDOperand Tmp" << ResNo << " = Transform_" << Op->getName() + << "(Tmp" << OpVal << ".Val);\n"; + if (isRoot) { + OS << " CodeGenMap[N] = Tmp" << ResNo << ";\n"; + OS << " return Tmp" << ResNo << ";\n"; } - } else if (HasCtrlDep) { - if (NumResults > 0) - OS << " SDOperand Result = "; - else - OS << " Chain = CodeGenMap[N] = "; - OS << "CurDAG->getTargetNode(" - << II.Namespace << "::" << II.TheDef->getName(); - if (NumResults > 0) - OS << ", MVT::" << getEnumName(N->getType()); // TODO: multiple results? - OS << ", MVT::Other"; - for (unsigned i = 0, e = Ops.size(); i != e; ++i) - OS << ", Tmp" << Ops[i]; - OS << ", Chain"; - if (InFlag) - OS << ", InFlag"; - OS << ");\n"; - if (NumResults > 0) { - OS << " CodeGenMap[N.getValue(0)] = Result;\n"; - OS << " CodeGenMap[N.getValue(" << NumResults - << ")] = Result.getValue(" << NumResults << ");\n"; - OS << " Chain = Result.getValue(" << NumResults << ");\n"; - } - if (NumResults == 0) - OS << " return Chain;\n"; - else - OS << " return (N.ResNo) ? Chain : Result.getValue(0);\n"; + return std::make_pair(1, ResNo); } else { - // If this instruction is the root, and if there is only one use of it, - // use SelectNodeTo instead of getTargetNode to avoid an allocation. - OS << " if (N.Val->hasOneUse()) {\n"; - OS << " return CurDAG->SelectNodeTo(N.Val, " - << II.Namespace << "::" << II.TheDef->getName() << ", MVT::" - << getEnumName(N->getType()); - for (unsigned i = 0, e = Ops.size(); i != e; ++i) - OS << ", Tmp" << Ops[i]; - if (InFlag) - OS << ", InFlag"; - OS << ");\n"; - OS << " } else {\n"; - OS << " return CodeGenMap[N] = CurDAG->getTargetNode(" - << II.Namespace << "::" << II.TheDef->getName() << ", MVT::" - << getEnumName(N->getType()); - for (unsigned i = 0, e = Ops.size(); i != e; ++i) - OS << ", Tmp" << Ops[i]; - if (InFlag) - OS << ", InFlag"; - OS << ");\n"; - OS << " }\n"; - } - return std::make_pair(1, ResNo); - } else if (Op->isSubClassOf("SDNodeXForm")) { - assert(N->getNumChildren() == 1 && "node xform should have one child!"); - unsigned OpVal = CodeGenPatternResult(M, N->getChild(0), Ctr, ChainName, - VariableMap, PatternNo, OS, InFlag) - .second; - - unsigned ResNo = Ctr++; - OS << " SDOperand Tmp" << ResNo << " = Transform_" << Op->getName() - << "(Tmp" << OpVal << ".Val);\n"; - if (isRoot) { - OS << " CodeGenMap[N] = Tmp" << ResNo << ";\n"; - OS << " return Tmp" << ResNo << ";\n"; - } - return std::make_pair(1, ResNo); - } else { - N->dump(); - assert(0 && "Unknown node in result pattern!"); - return std::make_pair(1, ~0U); + N->dump(); + assert(0 && "Unknown node in result pattern!"); + return std::make_pair(1, ~0U); + } } -} -/// RemoveAllTypes - A quick recursive walk over a pattern which removes all -/// type information from it. -static void RemoveAllTypes(TreePatternNode *N) { - N->setType(MVT::isUnknown); - if (!N->isLeaf()) - for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) - RemoveAllTypes(N->getChild(i)); -} - -/// InsertOneTypeCheck - Insert a type-check for an unresolved type in 'Pat' and -/// add it to the tree. 'Pat' and 'Other' are isomorphic trees except that -/// 'Pat' may be missing types. If we find an unresolved type to add a check -/// for, this returns true otherwise false if Pat has all types. -static bool InsertOneTypeCheck(TreePatternNode *Pat, TreePatternNode *Other, - DAGISelEmitter &ISE, - const std::string &Prefix, unsigned PatternNo, - std::ostream &OS) { - // Did we find one? - if (!Pat->hasTypeSet()) { - // Move a type over from 'other' to 'pat'. - Pat->setType(Other->getType()); - OS << " if (" << Prefix << ".Val->getValueType(0) != MVT::" - << getName(Pat->getType()) << ") goto P" << PatternNo << "Fail;\n"; - return true; - } else if (Pat->isLeaf()) { - if (NodeIsComplexPattern(Pat)) + /// InsertOneTypeCheck - Insert a type-check for an unresolved type in 'Pat' and + /// add it to the tree. 'Pat' and 'Other' are isomorphic trees except that + /// 'Pat' may be missing types. If we find an unresolved type to add a check + /// for, this returns true otherwise false if Pat has all types. + bool InsertOneTypeCheck(TreePatternNode *Pat, TreePatternNode *Other, + const std::string &Prefix) { + // Did we find one? + if (!Pat->hasTypeSet()) { + // Move a type over from 'other' to 'pat'. + Pat->setType(Other->getType()); OS << " if (" << Prefix << ".Val->getValueType(0) != MVT::" << getName(Pat->getType()) << ") goto P" << PatternNo << "Fail;\n"; + return true; + } else if (Pat->isLeaf()) { + if (NodeIsComplexPattern(Pat)) + OS << " if (" << Prefix << ".Val->getValueType(0) != MVT::" + << getName(Pat->getType()) << ") goto P" << PatternNo << "Fail;\n"; + return false; + } + + unsigned OpNo = (unsigned) NodeHasChain(Pat, ISE); + for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i, ++OpNo) + if (InsertOneTypeCheck(Pat->getChild(i), Other->getChild(i), + Prefix + utostr(OpNo))) + return true; return false; } - - unsigned OpNo = (unsigned) NodeHasChain(Pat, ISE); - for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i, ++OpNo) - if (InsertOneTypeCheck(Pat->getChild(i), Other->getChild(i), - ISE, Prefix + utostr(OpNo), PatternNo, OS)) - return true; - return false; -} -Record *DAGISelEmitter::getSDNodeNamed(const std::string &Name) const { - Record *N = Records.getDef(Name); - assert(N && N->isSubClassOf("SDNode") && "Bad argument"); - return N; -} +private: + /// EmitCopyToRegs - Emit the flag operands for the DAG that is + /// being built. + void EmitCopyToRegs(TreePatternNode *N, const std::string &RootName, + bool HasCtrlDep) { + const CodeGenTarget &T = ISE.getTargetInfo(); + unsigned OpNo = (unsigned) NodeHasChain(N, ISE); + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { + TreePatternNode *Child = N->getChild(i); + if (!Child->isLeaf()) { + EmitCopyToRegs(Child, RootName + utostr(OpNo), HasCtrlDep); + } else { + if (DefInit *DI = dynamic_cast(Child->getLeafValue())) { + Record *RR = DI->getDef(); + if (RR->isSubClassOf("Register")) { + MVT::ValueType RVT = getRegisterValueType(RR, T); + if (HasCtrlDep) { + OS << " SDOperand " << RootName << "CR" << i << ";\n"; + OS << " " << RootName << "CR" << i + << " = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(" + << ISE.getQualifiedName(RR) << ", MVT::" + << getEnumName(RVT) << ")" + << ", Select(" << RootName << OpNo << "), InFlag);\n"; + OS << " Chain = " << RootName << "CR" << i + << ".getValue(0);\n"; + OS << " InFlag = " << RootName << "CR" << i + << ".getValue(1);\n"; + } else { + OS << " InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode()" + << ", CurDAG->getRegister(" << ISE.getQualifiedName(RR) + << ", MVT::" << getEnumName(RVT) << ")" + << ", Select(" << RootName << OpNo + << "), InFlag).getValue(1);\n"; + } + } + } + } + } + } +}; /// EmitCodeForPattern - Given a pattern to match, emit code to the specified /// stream to match the pattern, and generate the code for the match if it @@ -2142,14 +2154,11 @@ OS << " // Pattern complexity = " << getPatternSize(Pattern.first, *this) << " cost = " << getResultPatternCost(Pattern.second) << "\n"; + PatternCodeEmitter Emitter(*this, Pattern.first, PatternNo, OS); + // Emit the matcher, capturing named arguments in VariableMap. - bool HasChain = false; - bool InFlag = false; - std::map VariableMap; - std::string ChainName; - EmitMatchForPattern(Pattern.first, "N", VariableMap, PatternNo, OS, - ChainName, HasChain, InFlag, true /*the root*/); - + Emitter.EmitMatchCode(Pattern.first, "N", true /*the root*/); + // TP - Get *SOME* tree pattern, we don't care which. TreePattern &TP = *PatternFragments.begin()->second; @@ -2183,12 +2192,10 @@ // Insert a check for an unresolved type and add it to the tree. If we find // an unresolved type to add a check for, this returns true and we iterate, // otherwise we are done. - } while (InsertOneTypeCheck(Pat, Pattern.first, *this, "N", PatternNo, OS)); + } while (Emitter.InsertOneTypeCheck(Pat, Pattern.first, "N")); + + Emitter.EmitResultCode(Pattern.second, true /*the root*/); - unsigned TmpNo = 0; - CodeGenPatternResult(Pattern.first, Pattern.second, - TmpNo, ChainName, VariableMap, PatternNo, OS, InFlag, - true /*the root*/); delete Pat; OS << " }\n P" << PatternNo << "Fail:\n"; Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.42 llvm/utils/TableGen/DAGISelEmitter.h:1.43 --- llvm/utils/TableGen/DAGISelEmitter.h:1.42 Fri Dec 9 00:06:08 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Fri Dec 9 16:45:35 2005 @@ -421,19 +421,6 @@ std::map &InstInputs, std::map &InstResults); - void EmitMatchForPattern(TreePatternNode *N, const std::string &RootName, - std::map &VarMap, - unsigned PatternNo, std::ostream &OS, - std::string &ChainName, - bool &HasChain, bool &InFlag, bool isRoot = false); - void EmitCopyToRegsForPattern(TreePatternNode *N, const std::string &RootName, - std::ostream &OS, bool HasChain); - std::pair - CodeGenPatternResult(TreePatternNode *M, TreePatternNode *N, unsigned &Ctr, - std::string &ChainName, - std::map &VariableMap, - unsigned PatternNo, std::ostream &OS, - bool InFlag, bool isRoot = false); void EmitCodeForPattern(PatternToMatch &Pattern, std::ostream &OS); void EmitInstructionSelector(std::ostream &OS); }; From evan.cheng at apple.com Fri Dec 9 16:49:01 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 9 Dec 2005 16:49:01 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200512092249.QAA02683@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.76 -> 1.77 --- Log message: Added patterns for ADD8rm, etc. These fold load operands. e.g. addb 4(%esp), %al --- Diffs of the changes: (+16 -0) SelectionDAG.h | 16 ++++++++++++++++ 1 files changed, 16 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.76 llvm/include/llvm/CodeGen/SelectionDAG.h:1.77 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.76 Wed Dec 7 20:00:35 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Fri Dec 9 16:48:48 2005 @@ -394,6 +394,22 @@ Ops.push_back(Op5); return getNode(ISD::BUILTIN_OP_END+Opcode, ResultTys, Ops); } + SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT1, + MVT::ValueType VT2, SDOperand Op1, SDOperand Op2, + SDOperand Op3, SDOperand Op4, SDOperand Op5, + SDOperand Op6) { + std::vector ResultTys; + ResultTys.push_back(VT1); + ResultTys.push_back(VT2); + std::vector Ops; + Ops.push_back(Op1); + Ops.push_back(Op2); + Ops.push_back(Op3); + Ops.push_back(Op4); + Ops.push_back(Op5); + Ops.push_back(Op6); + return getNode(ISD::BUILTIN_OP_END+Opcode, ResultTys, Ops); + } SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT1, MVT::ValueType VT2, std::vector &Ops) { std::vector ResultTys; From evan.cheng at apple.com Fri Dec 9 16:49:01 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 9 Dec 2005 16:49:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200512092249.QAA02687@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.150 -> 1.151 --- Log message: Added patterns for ADD8rm, etc. These fold load operands. e.g. addb 4(%esp), %al --- Diffs of the changes: (+6 -3) X86InstrInfo.td | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.150 llvm/lib/Target/X86/X86InstrInfo.td:1.151 --- llvm/lib/Target/X86/X86InstrInfo.td:1.150 Wed Dec 7 20:15:07 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Fri Dec 9 16:48:48 2005 @@ -1165,11 +1165,14 @@ } // end isConvertibleToThreeAddress } // end isCommutable def ADD8rm : I<0x02, MRMSrcMem, (ops R8 :$dst, R8 :$src1, i8mem :$src2), - "add{b} {$src2, $dst|$dst, $src2}", []>; + "add{b} {$src2, $dst|$dst, $src2}", + [(set R8:$dst, (add R8:$src1, (load addr:$src2)))]>; def ADD16rm : I<0x03, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2), - "add{w} {$src2, $dst|$dst, $src2}", []>, OpSize; + "add{w} {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (add R16:$src1, (load addr:$src2)))]>, OpSize; def ADD32rm : I<0x03, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2), - "add{l} {$src2, $dst|$dst, $src2}", []>; + "add{l} {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (add R32:$src1, (load addr:$src2)))]>; def ADD8ri : Ii8<0x80, MRM0r, (ops R8:$dst, R8:$src1, i8imm:$src2), "add{b} {$src2, $dst|$dst, $src2}", From lattner at cs.uiuc.edu Fri Dec 9 16:57:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Dec 2005 16:57:53 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200512092257.QAA02829@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.90 -> 1.91 DAGISelEmitter.h updated: 1.43 -> 1.44 --- Log message: Add a new SDTCisPtrTy constraint, which indicates that an operand must have the same type as the pointer type for a target. --- Diffs of the changes: (+8 -2) DAGISelEmitter.cpp | 6 ++++++ DAGISelEmitter.h | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.90 llvm/utils/TableGen/DAGISelEmitter.cpp:1.91 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.90 Fri Dec 9 16:45:35 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Dec 9 16:57:42 2005 @@ -58,6 +58,8 @@ if (R->isSubClassOf("SDTCisVT")) { ConstraintType = SDTCisVT; x.SDTCisVT_Info.VT = getValueType(R->getValueAsDef("VT")); + } else if (R->isSubClassOf("SDTCisPtrTy")) { + ConstraintType = SDTCisPtrTy; } else if (R->isSubClassOf("SDTCisInt")) { ConstraintType = SDTCisInt; } else if (R->isSubClassOf("SDTCisFP")) { @@ -120,6 +122,10 @@ case SDTCisVT: // Operand must be a particular type. return NodeToApply->UpdateNodeType(x.SDTCisVT_Info.VT, TP); + case SDTCisPtrTy: { + // Operand must be same as target pointer type. + return NodeToApply->UpdateNodeType(CGT.getPointerType(), TP); + } case SDTCisInt: { // If there is only one integer type supported, this must be it. std::vector IntVTs = Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.43 llvm/utils/TableGen/DAGISelEmitter.h:1.44 --- llvm/utils/TableGen/DAGISelEmitter.h:1.43 Fri Dec 9 16:45:35 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Fri Dec 9 16:57:42 2005 @@ -45,8 +45,8 @@ unsigned OperandNo; // The operand # this constraint applies to. enum { - SDTCisVT, SDTCisInt, SDTCisFP, SDTCisSameAs, SDTCisVTSmallerThanOp, - SDTCisOpSmallerThanOp + SDTCisVT, SDTCisPtrTy, SDTCisInt, SDTCisFP, SDTCisSameAs, + SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp } ConstraintType; union { // The discriminated union. From lattner at cs.uiuc.edu Fri Dec 9 16:58:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Dec 2005 16:58:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200512092258.QAA02886@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.13 -> 1.14 --- Log message: Add SDTCisPtrTy and use it for loads, to indicate that the operand of a load must be a pointer. This removes a type check out of the code generated by tblgen for load matching. --- Diffs of the changes: (+5 -3) TargetSelectionDAG.td | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.13 llvm/lib/Target/TargetSelectionDAG.td:1.14 --- llvm/lib/Target/TargetSelectionDAG.td:1.13 Wed Dec 7 22:28:48 2005 +++ llvm/lib/Target/TargetSelectionDAG.td Fri Dec 9 16:58:42 2005 @@ -24,15 +24,17 @@ } // SDTCisVT - The specified operand has exactly this VT. -class SDTCisVT : SDTypeConstraint { +class SDTCisVT : SDTypeConstraint { ValueType VT = vt; } +class SDTCisPtrTy : SDTypeConstraint; + // SDTCisInt - The specified operand is has integer type. class SDTCisInt : SDTypeConstraint; // SDTCisFP - The specified operand is has floating point type. -class SDTCisFP : SDTypeConstraint; +class SDTCisFP : SDTypeConstraint; // SDTCisSameAs - The two specified operands have identical types. class SDTCisSameAs : SDTypeConstraint { @@ -132,7 +134,7 @@ ]>; def SDTLoad : SDTypeProfile<1, 1, [ // load - SDTCisInt<1> + SDTCisPtrTy<1> ]>; //===----------------------------------------------------------------------===// From natebegeman at mac.com Fri Dec 9 17:54:29 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 9 Dec 2005 17:54:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCInstrFormats.td PPCInstrInfo.td Message-ID: <200512092354.RAA03398@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCInstrFormats.td updated: 1.60 -> 1.61 PPCInstrInfo.td updated: 1.152 -> 1.153 --- Log message: Add support patterns to many load and store instructions which will hopefully use patterns in the near future. --- Diffs of the changes: (+133 -76) PPCInstrFormats.td | 69 +++++++++++++++----------- PPCInstrInfo.td | 140 +++++++++++++++++++++++++++++++++++------------------ 2 files changed, 133 insertions(+), 76 deletions(-) Index: llvm/lib/Target/PowerPC/PPCInstrFormats.td diff -u llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.60 llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.61 --- llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.60 Sun Dec 4 12:42:54 2005 +++ llvm/lib/Target/PowerPC/PPCInstrFormats.td Fri Dec 9 17:54:17 2005 @@ -58,23 +58,27 @@ // 1.7.4 D-Form class DForm_base opcode, dag OL, string asmstr, InstrItinClass itin, - list pattern> - : I { - let Pattern = pattern; + list pattern> + : I { bits<5> A; bits<5> B; bits<16> C; + + let Pattern = pattern; let Inst{6-10} = A; let Inst{11-15} = B; let Inst{16-31} = C; } -class DForm_1 opcode, dag OL, string asmstr, InstrItinClass itin> - : I { +class DForm_1 opcode, dag OL, string asmstr, InstrItinClass itin, + list pattern> + : I { bits<5> A; bits<16> C; bits<5> B; + + let Pattern = pattern; let Inst{6-10} = A; let Inst{11-15} = B; @@ -99,12 +103,13 @@ } // Currently we make the use/def reg distinction in ISel, not tablegen -class DForm_3 opcode, dag OL, string asmstr, InstrItinClass itin> - : DForm_1; +class DForm_3 opcode, dag OL, string asmstr, InstrItinClass itin, + list pattern> + : DForm_1; class DForm_4 opcode, dag OL, string asmstr, InstrItinClass itin, list pattern> - : I { + : I { bits<5> B; bits<5> A; bits<16> C; @@ -116,8 +121,9 @@ let Inst{16-31} = C; } -class DForm_4_zero opcode, dag OL, string asmstr, InstrItinClass itin> - : DForm_1 { +class DForm_4_zero opcode, dag OL, string asmstr, InstrItinClass itin, + list pattern> + : DForm_1 { let A = 0; let B = 0; let C = 0; @@ -150,22 +156,26 @@ let L = PPC64; } -class DForm_8 opcode, dag OL, string asmstr, InstrItinClass itin> - : DForm_1 { +class DForm_8 opcode, dag OL, string asmstr, InstrItinClass itin, + list pattern> + : DForm_1 { } -class DForm_9 opcode, dag OL, string asmstr, InstrItinClass itin> - : DForm_1 { +class DForm_9 opcode, dag OL, string asmstr, InstrItinClass itin, + list pattern> + : DForm_1 { } // 1.7.5 DS-Form class DSForm_1 opcode, bits<2> xo, dag OL, string asmstr, - InstrItinClass itin> + InstrItinClass itin, list pattern> : I { bits<5> RST; bits<14> DS; bits<5> RA; + let Pattern = pattern; + let Inst{6-10} = RST; let Inst{11-15} = RA; let Inst{16-29} = DS; @@ -173,17 +183,19 @@ } class DSForm_2 opcode, bits<2> xo, dag OL, string asmstr, - InstrItinClass itin> - : DSForm_1; + InstrItinClass itin, list pattern> + : DSForm_1; // 1.7.6 X-Form -class XForm_base_r3xo opcode, bits<10> xo, - dag OL, string asmstr, InstrItinClass itin> +class XForm_base_r3xo opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin, list pattern> : I { bits<5> RST; bits<5> A; bits<5> B; + let Pattern = pattern; + bit RC = 0; // set by isDOT let Inst{6-10} = RST; @@ -214,8 +226,8 @@ class XForm_1 opcode, bits<10> xo, dag OL, string asmstr, - InstrItinClass itin> - : XForm_base_r3xo; + InstrItinClass itin, list pattern> + : XForm_base_r3xo; class XForm_6 opcode, bits<10> xo, dag OL, string asmstr, InstrItinClass itin, list pattern> @@ -224,8 +236,8 @@ } class XForm_8 opcode, bits<10> xo, dag OL, string asmstr, - InstrItinClass itin> - : XForm_base_r3xo; + InstrItinClass itin, list pattern> + : XForm_base_r3xo; class XForm_10 opcode, bits<10> xo, dag OL, string asmstr, InstrItinClass itin, list pattern> @@ -279,20 +291,19 @@ } class XForm_25 opcode, bits<10> xo, dag OL, string asmstr, - InstrItinClass itin> - : XForm_base_r3xo { + InstrItinClass itin, list pattern> + : XForm_base_r3xo { } class XForm_26 opcode, bits<10> xo, dag OL, string asmstr, InstrItinClass itin, list pattern> - : XForm_base_r3xo { + : XForm_base_r3xo { let A = 0; - let Pattern = pattern; } class XForm_28 opcode, bits<10> xo, dag OL, string asmstr, - InstrItinClass itin> - : XForm_base_r3xo { + InstrItinClass itin, list pattern> + : XForm_base_r3xo { } // 1.7.7 XL-Form Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.152 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.153 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.152 Mon Dec 5 20:10:38 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Fri Dec 9 17:54:18 2005 @@ -255,17 +255,23 @@ // let isLoad = 1 in { def LBZ : DForm_1<34, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), - "lbz $rD, $disp($rA)", LdStGeneral>; + "lbz $rD, $disp($rA)", LdStGeneral, + []>; def LHA : DForm_1<42, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), - "lha $rD, $disp($rA)", LdStLHA>; + "lha $rD, $disp($rA)", LdStLHA, + []>; def LHZ : DForm_1<40, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), - "lhz $rD, $disp($rA)", LdStGeneral>; + "lhz $rD, $disp($rA)", LdStGeneral, + []>; def LMW : DForm_1<46, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA), - "lmw $rD, $disp($rA)", LdStLMW>; + "lmw $rD, $disp($rA)", LdStLMW, + []>; def LWZ : DForm_1<32, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), - "lwz $rD, $disp($rA)", LdStGeneral>; + "lwz $rD, $disp($rA)", LdStGeneral, + []>; def LWZU : DForm_1<35, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA), - "lwzu $rD, $disp($rA)", LdStGeneral>; + "lwzu $rD, $disp($rA)", LdStGeneral, + []>; } def ADDI : DForm_2<14, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), "addi $rD, $rA, $imm", IntGeneral, @@ -297,15 +303,20 @@ [(set GPRC:$rD, imm16Shifted:$imm)]>; let isStore = 1 in { def STMW : DForm_3<47, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), - "stmw $rS, $disp($rA)", LdStLMW>; + "stmw $rS, $disp($rA)", LdStLMW, + []>; def STB : DForm_3<38, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), - "stb $rS, $disp($rA)", LdStGeneral>; + "stb $rS, $disp($rA)", LdStGeneral, + []>; def STH : DForm_3<44, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), - "sth $rS, $disp($rA)", LdStGeneral>; + "sth $rS, $disp($rA)", LdStGeneral, + []>; def STW : DForm_3<36, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), - "stw $rS, $disp($rA)", LdStGeneral>; + "stw $rS, $disp($rA)", LdStGeneral, + []>; def STWU : DForm_3<37, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), - "stwu $rS, $disp($rA)", LdStGeneral>; + "stwu $rS, $disp($rA)", LdStGeneral, + []>; } def ANDIo : DForm_4<28, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), "andi. $dst, $src1, $src2", IntGeneral, @@ -325,7 +336,8 @@ def XORIS : DForm_4<27, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), "xoris $dst, $src1, $src2", IntGeneral, [(set GPRC:$dst, (xor GPRC:$src1, imm16Shifted:$src2))]>; -def NOP : DForm_4_zero<24, (ops), "nop", IntGeneral>; +def NOP : DForm_4_zero<24, (ops), "nop", IntGeneral, + []>; def CMPI : DForm_5<11, (ops CRRC:$crD, i1imm:$L, GPRC:$rA, s16imm:$imm), "cmpi $crD, $L, $rA, $imm", IntCompare>; def CMPWI : DForm_5_ext<11, (ops CRRC:$crD, GPRC:$rA, s16imm:$imm), @@ -340,30 +352,38 @@ "cmpldi $dst, $src1, $src2", IntCompare>, isPPC64; let isLoad = 1 in { def LFS : DForm_8<48, (ops F4RC:$rD, symbolLo:$disp, GPRC:$rA), - "lfs $rD, $disp($rA)", LdStLFDU>; + "lfs $rD, $disp($rA)", LdStLFDU, + []>; def LFD : DForm_8<50, (ops F8RC:$rD, symbolLo:$disp, GPRC:$rA), - "lfd $rD, $disp($rA)", LdStLFD>; + "lfd $rD, $disp($rA)", LdStLFD, + []>; } let isStore = 1 in { def STFS : DForm_9<52, (ops F4RC:$rS, symbolLo:$disp, GPRC:$rA), - "stfs $rS, $disp($rA)", LdStUX>; + "stfs $rS, $disp($rA)", LdStUX, + []>; def STFD : DForm_9<54, (ops F8RC:$rS, symbolLo:$disp, GPRC:$rA), - "stfd $rS, $disp($rA)", LdStUX>; + "stfd $rS, $disp($rA)", LdStUX, + []>; } // DS-Form instructions. Load/Store instructions available in PPC-64 // let isLoad = 1 in { def LWA : DSForm_1<58, 2, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA), - "lwa $rT, $DS($rA)", LdStLWA>, isPPC64; + "lwa $rT, $DS($rA)", LdStLWA, + []>, isPPC64; def LD : DSForm_2<58, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA), - "ld $rT, $DS($rA)", LdStLD>, isPPC64; + "ld $rT, $DS($rA)", LdStLD, + []>, isPPC64; } let isStore = 1 in { def STD : DSForm_2<62, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA), - "std $rT, $DS($rA)", LdStSTD>, isPPC64; + "std $rT, $DS($rA)", LdStSTD, + []>, isPPC64; def STDU : DSForm_2<62, 1, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA), - "stdu $rT, $DS($rA)", LdStSTD>, isPPC64; + "stdu $rT, $DS($rA)", LdStSTD, + []>, isPPC64; } // X-Form instructions. Most instructions that perform an operation on a @@ -371,30 +391,42 @@ // let isLoad = 1 in { def LBZX : XForm_1<31, 87, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lbzx $dst, $base, $index", LdStGeneral>; + "lbzx $dst, $base, $index", LdStGeneral, + []>; def LHAX : XForm_1<31, 343, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lhax $dst, $base, $index", LdStLHA>; + "lhax $dst, $base, $index", LdStLHA, + []>; def LHZX : XForm_1<31, 279, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lhzx $dst, $base, $index", LdStGeneral>; + "lhzx $dst, $base, $index", LdStGeneral, + []>; def LWAX : XForm_1<31, 341, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lwax $dst, $base, $index", LdStLHA>, isPPC64; + "lwax $dst, $base, $index", LdStLHA, + []>, isPPC64; def LWZX : XForm_1<31, 23, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lwzx $dst, $base, $index", LdStGeneral>; + "lwzx $dst, $base, $index", LdStGeneral, + []>; def LDX : XForm_1<31, 21, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "ldx $dst, $base, $index", LdStLD>, isPPC64; + "ldx $dst, $base, $index", LdStLD, + []>, isPPC64; def LVEBX: XForm_1<31, 7, (ops VRRC:$vD, GPRC:$base, GPRC:$rA), - "lvebx $vD, $base, $rA", LdStGeneral>; + "lvebx $vD, $base, $rA", LdStGeneral, + []>; def LVEHX: XForm_1<31, 39, (ops VRRC:$vD, GPRC:$base, GPRC:$rA), - "lvehx $vD, $base, $rA", LdStGeneral>; + "lvehx $vD, $base, $rA", LdStGeneral, + []>; def LVEWX: XForm_1<31, 71, (ops VRRC:$vD, GPRC:$base, GPRC:$rA), - "lvewx $vD, $base, $rA", LdStGeneral>; + "lvewx $vD, $base, $rA", LdStGeneral, + []>; def LVX : XForm_1<31, 103, (ops VRRC:$vD, GPRC:$base, GPRC:$rA), - "lvx $vD, $base, $rA", LdStGeneral>; + "lvx $vD, $base, $rA", LdStGeneral, + []>; +} def LVSL : XForm_1<31, 6, (ops VRRC:$vD, GPRC:$base, GPRC:$rA), - "lvsl $vD, $base, $rA", LdStGeneral>; + "lvsl $vD, $base, $rA", LdStGeneral, + []>; def LVSR : XForm_1<31, 38, (ops VRRC:$vD, GPRC:$base, GPRC:$rA), - "lvsl $vD, $base, $rA", LdStGeneral>; -} + "lvsl $vD, $base, $rA", LdStGeneral, + []>; def NAND : XForm_6<31, 476, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "nand $rA, $rS, $rB", IntGeneral, [(set GPRC:$rA, (not (and GPRC:$rS, GPRC:$rB)))]>; @@ -454,25 +486,35 @@ [(set GPRC:$rA, (PPCsra 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", LdStGeneral>; + "stbx $rS, $rA, $rB", LdStGeneral, + []>; def STHX : XForm_8<31, 407, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "sthx $rS, $rA, $rB", LdStGeneral>; + "sthx $rS, $rA, $rB", LdStGeneral, + []>; def STWX : XForm_8<31, 151, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "stwx $rS, $rA, $rB", LdStGeneral>; + "stwx $rS, $rA, $rB", LdStGeneral, + []>; def STWUX : XForm_8<31, 183, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "stwux $rS, $rA, $rB", LdStGeneral>; + "stwux $rS, $rA, $rB", LdStGeneral, + []>; def STDX : XForm_8<31, 149, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "stdx $rS, $rA, $rB", LdStSTD>, isPPC64; + "stdx $rS, $rA, $rB", LdStSTD, + []>, isPPC64; def STDUX : XForm_8<31, 181, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "stdux $rS, $rA, $rB", LdStSTD>, isPPC64; + "stdux $rS, $rA, $rB", LdStSTD, + []>, isPPC64; def STVEBX: XForm_8<31, 135, (ops VRRC:$rS, GPRC:$rA, GPRC:$rB), - "stvebx $rS, $rA, $rB", LdStGeneral>; + "stvebx $rS, $rA, $rB", LdStGeneral, + []>; def STVEHX: XForm_8<31, 167, (ops VRRC:$rS, GPRC:$rA, GPRC:$rB), - "stvehx $rS, $rA, $rB", LdStGeneral>; + "stvehx $rS, $rA, $rB", LdStGeneral, + []>; def STVEWX: XForm_8<31, 199, (ops VRRC:$rS, GPRC:$rA, GPRC:$rB), - "stvewx $rS, $rA, $rB", LdStGeneral>; + "stvewx $rS, $rA, $rB", LdStGeneral, + []>; def STVX : XForm_8<31, 231, (ops VRRC:$rS, GPRC:$rA, GPRC:$rB), - "stvx $rS, $rA, $rB", LdStGeneral>; + "stvx $rS, $rA, $rB", LdStGeneral, + []>; } def SRAWI : XForm_10<31, 824, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH), "srawi $rA, $rS, $SH", IntShift, @@ -510,9 +552,11 @@ let isLoad = 1 in { def LFSX : XForm_25<31, 535, (ops F4RC:$dst, GPRC:$base, GPRC:$index), - "lfsx $dst, $base, $index", LdStLFDU>; + "lfsx $dst, $base, $index", LdStLFDU, + []>; def LFDX : XForm_25<31, 599, (ops F8RC:$dst, GPRC:$base, GPRC:$index), - "lfdx $dst, $base, $index", LdStLFDU>; + "lfdx $dst, $base, $index", LdStLFDU, + []>; } def FCFID : XForm_26<63, 846, (ops F8RC:$frD, F8RC:$frB), "fcfid $frD, $frB", FPGeneral, @@ -567,9 +611,11 @@ let isStore = 1 in { def STFSX : XForm_28<31, 663, (ops F4RC:$frS, GPRC:$rA, GPRC:$rB), - "stfsx $frS, $rA, $rB", LdStUX>; + "stfsx $frS, $rA, $rB", LdStUX, + []>; def STFDX : XForm_28<31, 727, (ops F8RC:$frS, GPRC:$rA, GPRC:$rB), - "stfdx $frS, $rA, $rB", LdStUX>; + "stfdx $frS, $rA, $rB", LdStUX, + []>; } // XL-Form instructions. condition register logical ops. From evan.cheng at apple.com Fri Dec 9 18:09:29 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 9 Dec 2005 18:09:29 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200512100009.SAA03555@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.91 -> 1.92 --- Log message: For instructions which produce no result, e.g. store, chain's Resno == 0. --- Diffs of the changes: (+6 -4) DAGISelEmitter.cpp | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.91 llvm/utils/TableGen/DAGISelEmitter.cpp:1.92 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.91 Fri Dec 9 16:57:42 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Dec 9 18:09:17 2005 @@ -1779,10 +1779,11 @@ if (NodeHasChain(N, ISE)) { OpNo = 1; if (!isRoot) { + const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator()); OS << " if (!" << RootName << ".hasOneUse()) goto P" << PatternNo << "Fail; // Multiple uses of actual result?\n"; OS << " if (CodeGenMap.count(" << RootName - << ".getValue(1))) goto P" + << ".getValue(" << CInfo.getNumResults() << "))) goto P" << PatternNo << "Fail; // Already selected for a chain use?\n"; } if (InnerChain.empty()) { @@ -2024,10 +2025,11 @@ } OS << " Chain "; if (NodeHasChain(LHS, ISE)) - OS << "= CodeGenMap[N.getValue(1)] "; + OS << "= CodeGenMap[N.getValue(" << NumResults << ")] "; for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) - OS << "= CodeGenMap[" << FoldedChains[j] << ".getValue(1)] "; - OS << "= Result.getValue(1);\n"; + OS << "= CodeGenMap[" << FoldedChains[j] << ".getValue(" + << NumResults << ")] "; + OS << "= Result.getValue(" << NumResults << ");\n"; if (NumResults == 0) OS << " return Chain;\n"; else From evan.cheng at apple.com Fri Dec 9 18:38:10 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 9 Dec 2005 18:38:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200512100038.SAA03727@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.223 -> 1.224 --- Log message: Added new getNode and getTargetNode variants for X86 stores. --- Diffs of the changes: (+73 -60) SelectionDAG.cpp | 133 ++++++++++++++++++++++++++++++------------------------- 1 files changed, 73 insertions(+), 60 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.223 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.224 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.223 Tue Dec 6 00:18:55 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Dec 9 18:37:58 2005 @@ -1088,66 +1088,6 @@ return SDOperand(N, 0); } -// setAdjCallChain - This method changes the token chain of an -// CALLSEQ_START/END node to be the specified operand. -void SDNode::setAdjCallChain(SDOperand N) { - assert(N.getValueType() == MVT::Other); - assert((getOpcode() == ISD::CALLSEQ_START || - getOpcode() == ISD::CALLSEQ_END) && "Cannot adjust this node!"); - - OperandList[0].Val->removeUser(this); - OperandList[0] = N; - OperandList[0].Val->Uses.push_back(this); -} - - - -SDOperand SelectionDAG::getLoad(MVT::ValueType VT, - SDOperand Chain, SDOperand Ptr, - SDOperand SV) { - SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, VT))]; - if (N) return SDOperand(N, 0); - N = new SDNode(ISD::LOAD, Chain, Ptr, SV); - - // Loads have a token chain. - setNodeValueTypes(N, VT, MVT::Other); - AllNodes.push_back(N); - return SDOperand(N, 0); -} - -SDOperand SelectionDAG::getVecLoad(unsigned Count, MVT::ValueType EVT, - SDOperand Chain, SDOperand Ptr, - SDOperand SV) { - SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, EVT))]; - if (N) return SDOperand(N, 0); - std::vector Ops; - Ops.reserve(5); - Ops.push_back(Chain); - Ops.push_back(Ptr); - Ops.push_back(getConstant(Count, MVT::i32)); - Ops.push_back(getValueType(EVT)); - Ops.push_back(SV); - std::vector VTs; - VTs.reserve(2); - VTs.push_back(MVT::Vector); VTs.push_back(MVT::Other); // Add token chain. - return getNode(ISD::VLOAD, VTs, Ops); -} - -SDOperand SelectionDAG::getExtLoad(unsigned Opcode, MVT::ValueType VT, - SDOperand Chain, SDOperand Ptr, SDOperand SV, - MVT::ValueType EVT) { - std::vector Ops; - Ops.reserve(4); - Ops.push_back(Chain); - Ops.push_back(Ptr); - Ops.push_back(SV); - Ops.push_back(getValueType(EVT)); - std::vector VTs; - VTs.reserve(2); - VTs.push_back(VT); VTs.push_back(MVT::Other); // Add token chain. - return getNode(Opcode, VTs, Ops); -} - SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1, SDOperand N2, SDOperand N3) { // Perform various simplifications. @@ -1224,6 +1164,79 @@ return getNode(Opcode, VT, Ops); } +SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, + SDOperand N1, SDOperand N2, SDOperand N3, + SDOperand N4, SDOperand N5, SDOperand N6) { + std::vector Ops; + Ops.reserve(6); + Ops.push_back(N1); + Ops.push_back(N2); + Ops.push_back(N3); + Ops.push_back(N4); + Ops.push_back(N5); + Ops.push_back(N6); + return getNode(Opcode, VT, Ops); +} + +// setAdjCallChain - This method changes the token chain of an +// CALLSEQ_START/END node to be the specified operand. +void SDNode::setAdjCallChain(SDOperand N) { + assert(N.getValueType() == MVT::Other); + assert((getOpcode() == ISD::CALLSEQ_START || + getOpcode() == ISD::CALLSEQ_END) && "Cannot adjust this node!"); + + OperandList[0].Val->removeUser(this); + OperandList[0] = N; + OperandList[0].Val->Uses.push_back(this); +} + + + +SDOperand SelectionDAG::getLoad(MVT::ValueType VT, + SDOperand Chain, SDOperand Ptr, + SDOperand SV) { + SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, VT))]; + if (N) return SDOperand(N, 0); + N = new SDNode(ISD::LOAD, Chain, Ptr, SV); + + // Loads have a token chain. + setNodeValueTypes(N, VT, MVT::Other); + AllNodes.push_back(N); + return SDOperand(N, 0); +} + +SDOperand SelectionDAG::getVecLoad(unsigned Count, MVT::ValueType EVT, + SDOperand Chain, SDOperand Ptr, + SDOperand SV) { + SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, EVT))]; + if (N) return SDOperand(N, 0); + std::vector Ops; + Ops.reserve(5); + Ops.push_back(Chain); + Ops.push_back(Ptr); + Ops.push_back(getConstant(Count, MVT::i32)); + Ops.push_back(getValueType(EVT)); + Ops.push_back(SV); + std::vector VTs; + VTs.reserve(2); + VTs.push_back(MVT::Vector); VTs.push_back(MVT::Other); // Add token chain. + return getNode(ISD::VLOAD, VTs, Ops); +} + +SDOperand SelectionDAG::getExtLoad(unsigned Opcode, MVT::ValueType VT, + SDOperand Chain, SDOperand Ptr, SDOperand SV, + MVT::ValueType EVT) { + std::vector Ops; + Ops.reserve(4); + Ops.push_back(Chain); + Ops.push_back(Ptr); + Ops.push_back(SV); + Ops.push_back(getValueType(EVT)); + std::vector VTs; + VTs.reserve(2); + VTs.push_back(VT); VTs.push_back(MVT::Other); // Add token chain. + return getNode(Opcode, VTs, Ops); +} SDOperand SelectionDAG::getSrcValue(const Value *V, int Offset) { assert((!V || isa(V->getType())) && From evan.cheng at apple.com Fri Dec 9 18:38:10 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 9 Dec 2005 18:38:10 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200512100038.SAA03731@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.77 -> 1.78 --- Log message: Added new getNode and getTargetNode variants for X86 stores. --- Diffs of the changes: (+8 -0) SelectionDAG.h | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.77 llvm/include/llvm/CodeGen/SelectionDAG.h:1.78 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.77 Fri Dec 9 16:48:48 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Fri Dec 9 18:37:58 2005 @@ -233,6 +233,9 @@ SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4, SDOperand N5); SDOperand getNode(unsigned Opcode, MVT::ValueType VT, + SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4, + SDOperand N5, SDOperand N6); + SDOperand getNode(unsigned Opcode, MVT::ValueType VT, std::vector &Children); SDOperand getNode(unsigned Opcode, std::vector &ResultTys, std::vector &Ops); @@ -342,6 +345,11 @@ return getNode(ISD::BUILTIN_OP_END+Opcode, VT, Op1, Op2, Op3, Op4, Op5); } SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT, + SDOperand Op1, SDOperand Op2, SDOperand Op3, + SDOperand Op4, SDOperand Op5, SDOperand Op6) { + return getNode(ISD::BUILTIN_OP_END+Opcode, VT, Op1, Op2, Op3, Op4, Op5, Op6); + } + SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT, std::vector &Ops) { return getNode(ISD::BUILTIN_OP_END+Opcode, VT, Ops); } From evan.cheng at apple.com Fri Dec 9 18:48:32 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 9 Dec 2005 18:48:32 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200512100048.SAA03792@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.14 -> 1.15 --- Log message: * Added X86 store patterns. * Added X86 dec patterns. --- Diffs of the changes: (+5 -0) TargetSelectionDAG.td | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.14 llvm/lib/Target/TargetSelectionDAG.td:1.15 --- llvm/lib/Target/TargetSelectionDAG.td:1.14 Fri Dec 9 16:58:42 2005 +++ llvm/lib/Target/TargetSelectionDAG.td Fri Dec 9 18:48:20 2005 @@ -137,6 +137,10 @@ SDTCisPtrTy<1> ]>; +def SDTStore : SDTypeProfile<0, 2, [ // store + SDTCisInt<1> +]>; + //===----------------------------------------------------------------------===// // Selection DAG Node Properties. // @@ -227,6 +231,7 @@ def writeport : SDNode<"ISD::WRITEPORT" , SDTWritePort, [SDNPHasChain]>; def load : SDNode<"ISD::LOAD" , SDTLoad, [SDNPHasChain]>; +def store : SDNode<"ISD::STORE" , SDTStore, [SDNPHasChain]>; //===----------------------------------------------------------------------===// // Selection DAG Condition Codes From evan.cheng at apple.com Fri Dec 9 18:48:32 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 9 Dec 2005 18:48:32 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp X86InstrInfo.td Message-ID: <200512100048.SAA03798@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.7 -> 1.8 X86InstrInfo.td updated: 1.151 -> 1.152 --- Log message: * Added X86 store patterns. * Added X86 dec patterns. --- Diffs of the changes: (+19 -43) X86ISelDAGToDAG.cpp | 33 --------------------------------- X86InstrInfo.td | 29 +++++++++++++++++++---------- 2 files changed, 19 insertions(+), 43 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.7 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.8 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.7 Wed Dec 7 20:01:35 2005 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Fri Dec 9 18:48:20 2005 @@ -387,39 +387,6 @@ getI16Imm(X86Lowering.getBytesToPopOnReturn()), Chain); } - - case ISD::STORE: { - SDOperand Chain = Select(N->getOperand(0)); // Token chain. - SDOperand Tmp1 = Select(N->getOperand(1)); - Opc = 0; - if (ConstantSDNode *CN = dyn_cast(N->getOperand(1))) { - switch (CN->getValueType(0)) { - default: assert(0 && "Invalid type for operation!"); - case MVT::i1: - case MVT::i8: Opc = X86::MOV8mi; break; - case MVT::i16: Opc = X86::MOV16mi; break; - case MVT::i32: Opc = X86::MOV32mi; break; - } - } - - if (!Opc) { - switch (N->getOperand(1).getValueType()) { - default: assert(0 && "Cannot store this type!"); - case MVT::i1: - case MVT::i8: Opc = X86::MOV8mr; break; - case MVT::i16: Opc = X86::MOV16mr; break; - case MVT::i32: Opc = X86::MOV32mr; break; - case MVT::f32: Opc = X86::MOVSSmr; break; - case MVT::f64: Opc = X86::FST64m; break; - } - } - - SDOperand Base, Scale, Index, Disp; - SelectAddr(N->getOperand(2), Base, Scale, Index, Disp); - return CurDAG->SelectNodeTo(N, Opc, MVT::Other, - Base, Scale, Index, Disp, Tmp1, Chain) - .getValue(Op.ResNo); - } } return SelectCode(Op); Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.151 llvm/lib/Target/X86/X86InstrInfo.td:1.152 --- llvm/lib/Target/X86/X86InstrInfo.td:1.151 Fri Dec 9 16:48:48 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Fri Dec 9 18:48:20 2005 @@ -378,11 +378,14 @@ "mov{l} {$src, $dst|$dst, $src}", [(set R32:$dst, imm:$src)]>; def MOV8mi : Ii8 <0xC6, MRM0m, (ops i8mem :$dst, i8imm :$src), - "mov{b} {$src, $dst|$dst, $src}", []>; + "mov{b} {$src, $dst|$dst, $src}", + [(store (i8 imm:$src), addr:$dst)]>; def MOV16mi : Ii16<0xC7, MRM0m, (ops i16mem:$dst, i16imm:$src), - "mov{w} {$src, $dst|$dst, $src}", []>, OpSize; + "mov{w} {$src, $dst|$dst, $src}", + [(store (i16 imm:$src), addr:$dst)]>, OpSize; def MOV32mi : Ii32<0xC7, MRM0m, (ops i32mem:$dst, i32imm:$src), - "mov{l} {$src, $dst|$dst, $src}", []>; + "mov{l} {$src, $dst|$dst, $src}", + [(store (i32 imm:$src), addr:$dst)]>; def MOV8rm : I<0x8A, MRMSrcMem, (ops R8 :$dst, i8mem :$src), "mov{b} {$src, $dst|$dst, $src}", @@ -395,11 +398,14 @@ [(set R32:$dst, (load addr:$src))]>; def MOV8mr : I<0x88, MRMDestMem, (ops i8mem :$dst, R8 :$src), - "mov{b} {$src, $dst|$dst, $src}", []>; + "mov{b} {$src, $dst|$dst, $src}", + [(store R8:$src, addr:$dst)]>; def MOV16mr : I<0x89, MRMDestMem, (ops i16mem:$dst, R16:$src), - "mov{w} {$src, $dst|$dst, $src}", []>, OpSize; + "mov{w} {$src, $dst|$dst, $src}", + [(store R16:$src, addr:$dst)]>, OpSize; def MOV32mr : I<0x89, MRMDestMem, (ops i32mem:$dst, R32:$src), - "mov{l} {$src, $dst|$dst, $src}", []>; + "mov{l} {$src, $dst|$dst, $src}", + [(store R32:$src, addr:$dst)]>; //===----------------------------------------------------------------------===// // Fixed-Register Multiplication and Division Instructions... @@ -687,6 +693,7 @@ def NOT32m : I<0xF7, MRM2m, (ops i32mem:$dst), "not{l} $dst", []>; } +// TODO: inc/dec is slow for P4, but fast for Pentium-M. def INC8r : I<0xFE, MRM0r, (ops R8 :$dst, R8 :$src), "inc{b} $dst", [(set R8:$dst, (add R8:$src, 1))]>; let isConvertibleToThreeAddress = 1 in { // Can transform into LEA. @@ -701,11 +708,13 @@ def INC32m : I<0xFF, MRM0m, (ops i32mem:$dst), "inc{l} $dst", []>; } -def DEC8r : I<0xFE, MRM1r, (ops R8 :$dst, R8 :$src), "dec{b} $dst", []>; +def DEC8r : I<0xFE, MRM1r, (ops R8 :$dst, R8 :$src), "dec{b} $dst", + [(set R8:$dst, (add R8:$src, -1))]>; let isConvertibleToThreeAddress = 1 in { // Can transform into LEA. -def DEC16r : I<0xFF, MRM1r, (ops R16:$dst, R16:$src), "dec{w} $dst", []>, - OpSize; -def DEC32r : I<0xFF, MRM1r, (ops R32:$dst, R32:$src), "dec{l} $dst", []>; +def DEC16r : I<0xFF, MRM1r, (ops R16:$dst, R16:$src), "dec{w} $dst", + [(set R16:$dst, (add R16:$src, -1))]>, OpSize; +def DEC32r : I<0xFF, MRM1r, (ops R32:$dst, R32:$src), "dec{l} $dst", + [(set R32:$dst, (add R32:$src, -1))]>; } let isTwoAddress = 0 in { From evan.cheng at apple.com Fri Dec 9 19:57:46 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 9 Dec 2005 19:57:46 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200512100157.TAA04104@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.92 -> 1.93 --- Log message: Stop emitting a redudant type check for complex pattern node. --- Diffs of the changes: (+0 -5) DAGISelEmitter.cpp | 5 ----- 1 files changed, 5 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.92 llvm/utils/TableGen/DAGISelEmitter.cpp:1.93 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.92 Fri Dec 9 18:09:17 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Dec 9 19:57:33 2005 @@ -2091,11 +2091,6 @@ OS << " if (" << Prefix << ".Val->getValueType(0) != MVT::" << getName(Pat->getType()) << ") goto P" << PatternNo << "Fail;\n"; return true; - } else if (Pat->isLeaf()) { - if (NodeIsComplexPattern(Pat)) - OS << " if (" << Prefix << ".Val->getValueType(0) != MVT::" - << getName(Pat->getType()) << ") goto P" << PatternNo << "Fail;\n"; - return false; } unsigned OpNo = (unsigned) NodeHasChain(Pat, ISE); From evan.cheng at apple.com Fri Dec 9 19:59:47 2005 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 9 Dec 2005 19:59:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200512100159.TAA04127@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.15 -> 1.16 --- Log message: Use SDTCisPtrTy type property for store address. --- Diffs of the changes: (+2 -2) TargetSelectionDAG.td | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.15 llvm/lib/Target/TargetSelectionDAG.td:1.16 --- llvm/lib/Target/TargetSelectionDAG.td:1.15 Fri Dec 9 18:48:20 2005 +++ llvm/lib/Target/TargetSelectionDAG.td Fri Dec 9 19:59:36 2005 @@ -138,7 +138,7 @@ ]>; def SDTStore : SDTypeProfile<0, 2, [ // store - SDTCisInt<1> + SDTCisPtrTy<1> ]>; //===----------------------------------------------------------------------===// @@ -230,7 +230,7 @@ def writeport : SDNode<"ISD::WRITEPORT" , SDTWritePort, [SDNPHasChain]>; -def load : SDNode<"ISD::LOAD" , SDTLoad, [SDNPHasChain]>; +def load : SDNode<"ISD::LOAD" , SDTLoad, [SDNPHasChain]>; def store : SDNode<"ISD::STORE" , SDTStore, [SDNPHasChain]>; //===----------------------------------------------------------------------===// From natebegeman at mac.com Fri Dec 9 20:36:13 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 9 Dec 2005 20:36:13 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp PPCISelLowering.cpp PPCInstrInfo.td Message-ID: <200512100236.UAA04308@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.139 -> 1.140 PPCISelLowering.cpp updated: 1.49 -> 1.50 PPCInstrInfo.td updated: 1.153 -> 1.154 --- Log message: Add support for TargetConstantPool nodes to the dag isel emitter, and use them in the PPC backend, to simplify some logic out of Select and SelectAddr. --- Diffs of the changes: (+40 -29) PPCISelDAGToDAG.cpp | 29 +++++------------------------ PPCISelLowering.cpp | 35 +++++++++++++++++++++++++++++++---- PPCInstrInfo.td | 5 ++++- 3 files changed, 40 insertions(+), 29 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.139 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.140 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.139 Tue Dec 6 14:56:18 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Fri Dec 9 20:36:00 2005 @@ -423,7 +423,8 @@ assert(!cast(Addr.getOperand(1).getOperand(1))->getValue() && "Cannot handle constant offsets yet!"); Op1 = Addr.getOperand(1).getOperand(0); // The global address. - assert(Op1.getOpcode() == ISD::TargetGlobalAddress); + assert(Op1.getOpcode() == ISD::TargetGlobalAddress || + Op1.getOpcode() == ISD::TargetConstantPool); Op2 = Select(Addr.getOperand(0)); return false; // [&g+r] } else { @@ -433,20 +434,11 @@ } } - if (FrameIndexSDNode *FI = dyn_cast(Addr)) { - Op1 = getI32Imm(0); + if (FrameIndexSDNode *FI = dyn_cast(Addr)) Op2 = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); - return false; - } else if (ConstantPoolSDNode *CP = dyn_cast(Addr)) { - Op1 = Addr; - if (PICEnabled) - Op2 = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),Op1); - else - Op2 = CurDAG->getTargetNode(PPC::LIS, MVT::i32, Op1); - return false; - } + else + Op2 = Select(Addr); Op1 = getI32Imm(0); - Op2 = Select(Addr); return false; } @@ -893,17 +885,6 @@ CurDAG->getTargetFrameIndex(FI, MVT::i32), getI32Imm(0)); } - case ISD::ConstantPool: { - Constant *C = cast(N)->get(); - SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i32); - if (PICEnabled) - Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),CPI); - else - Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, CPI); - if (N->hasOneUse()) - return CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, CPI); - return CodeGenMap[Op] = CurDAG->getTargetNode(PPC::LA, MVT::i32, Tmp, CPI); - } case ISD::FADD: { MVT::ValueType Ty = N->getValueType(0); if (!NoExcessFPPrecision) { // Match FMA ops Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.49 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.50 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.49 Mon Dec 5 20:10:38 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Fri Dec 9 20:36:00 2005 @@ -94,9 +94,10 @@ // PowerPC doesn't have line number support yet. setOperationAction(ISD::LOCATION, MVT::Other, Expand); - // We want to legalize GlobalAddress into the appropriate instructions to - // materialize the address. + // We want to legalize GlobalAddress and ConstantPool nodes into the + // appropriate instructions to materialize the address. setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); + setOperationAction(ISD::ConstantPool, MVT::i32, Custom); if (TM.getSubtarget().is64Bit()) { // They also have instructions for converting between i64 and fp. @@ -341,14 +342,40 @@ Tmp4, Tmp6, ISD::SETLE); return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); } + case ISD::ConstantPool: { + Constant *C = cast(Op)->get(); + SDOperand CPI = DAG.getTargetConstantPool(C, MVT::i32); + SDOperand Zero = DAG.getConstant(0, MVT::i32); + + if (PPCGenerateStaticCode) { + // Generate non-pic code that has direct accesses to the constant pool. + // The address of the global is just (hi(&g)+lo(&g)). + SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, CPI, Zero); + SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, CPI, Zero); + return DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + } + + // Only lower ConstantPool on Darwin. + if (!getTargetMachine().getSubtarget().isDarwin()) break; + SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, CPI, Zero); + if (PICEnabled) { + // With PIC, the first instruction is actually "GR+hi(&G)". + Hi = DAG.getNode(ISD::ADD, MVT::i32, + DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); + } + + SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, CPI, Zero); + Lo = DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + return Lo; + } case ISD::GlobalAddress: { GlobalValue *GV = cast(Op)->getGlobal(); SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32); SDOperand Zero = DAG.getConstant(0, MVT::i32); if (PPCGenerateStaticCode) { - // Generate non-pic code that has direct accesses to globals. To do this - // the address of the global is just (hi(&g)+lo(&g)). + // Generate non-pic code that has direct accesses to globals. + // The address of the global is just (hi(&g)+lo(&g)). SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero); SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, GA, Zero); return DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.153 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.154 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.153 Fri Dec 9 17:54:18 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Fri Dec 9 20:36:00 2005 @@ -165,7 +165,6 @@ } - //===----------------------------------------------------------------------===// // PowerPC Instruction Definitions. @@ -943,8 +942,12 @@ // Hi and Lo for Darwin Global Addresses. def : Pat<(PPChi tglobaladdr:$in, (i32 0)), (LIS tglobaladdr:$in)>; def : Pat<(PPClo tglobaladdr:$in, (i32 0)), (LI tglobaladdr:$in)>; +def : Pat<(PPChi tconstpool:$in, (i32 0)), (LIS tconstpool:$in)>; +def : Pat<(PPClo tconstpool:$in, (i32 0)), (LI tconstpool:$in)>; def : Pat<(add GPRC:$in, (PPChi tglobaladdr:$g, 0)), (ADDIS GPRC:$in, tglobaladdr:$g)>; +def : Pat<(add GPRC:$in, (PPChi tconstpool:$g, 0)), + (ADDIS GPRC:$in, tconstpool:$g)>; // Standard shifts. These are represented separately from the real shifts above // so that we can distinguish between shifts that allow 5-bit and 6-bit shift From natebegeman at mac.com Fri Dec 9 20:36:13 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 9 Dec 2005 20:36:13 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200512100236.UAA04312@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.225 -> 1.226 --- Log message: Add support for TargetConstantPool nodes to the dag isel emitter, and use them in the PPC backend, to simplify some logic out of Select and SelectAddr. --- Diffs of the changes: (+3 -1) LegalizeDAG.cpp | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.225 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.226 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.225 Fri Dec 9 11:32:47 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Dec 9 20:36:00 2005 @@ -532,6 +532,7 @@ case ISD::TargetFrameIndex: case ISD::Register: case ISD::TargetConstant: + case ISD::TargetConstantPool: case ISD::GlobalAddress: case ISD::TargetGlobalAddress: case ISD::ExternalSymbol: @@ -679,7 +680,8 @@ Extend = true; } - SDOperand CPIdx = DAG.getConstantPool(LLVMC, TLI.getPointerTy()); + SDOperand CPIdx = + LegalizeOp(DAG.getConstantPool(LLVMC, TLI.getPointerTy())); if (Extend) { Result = DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), CPIdx, DAG.getSrcValue(NULL), MVT::f32); From natebegeman at mac.com Fri Dec 9 20:36:13 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 9 Dec 2005 20:36:13 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200512100236.UAA04320@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.16 -> 1.17 --- Log message: Add support for TargetConstantPool nodes to the dag isel emitter, and use them in the PPC backend, to simplify some logic out of Select and SelectAddr. --- Diffs of the changes: (+2 -0) TargetSelectionDAG.td | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.16 llvm/lib/Target/TargetSelectionDAG.td:1.17 --- llvm/lib/Target/TargetSelectionDAG.td:1.16 Fri Dec 9 19:59:36 2005 +++ llvm/lib/Target/TargetSelectionDAG.td Fri Dec 9 20:36:00 2005 @@ -174,6 +174,8 @@ "GlobalAddressSDNode">; def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTImm, [], "GlobalAddressSDNode">; +def tconstpool : SDNode<"ISD::TargetConstantPool", SDTImm, [], + "ConstantPoolSDNode">; def add : SDNode<"ISD::ADD" , SDTIntBinOp , [SDNPCommutative, SDNPAssociative]>; def sub : SDNode<"ISD::SUB" , SDTIntBinOp>; From natebegeman at mac.com Fri Dec 9 20:36:13 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 9 Dec 2005 20:36:13 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200512100236.UAA04316@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.93 -> 1.94 --- Log message: Add support for TargetConstantPool nodes to the dag isel emitter, and use them in the PPC backend, to simplify some logic out of Select and SelectAddr. --- Diffs of the changes: (+2 -0) DAGISelEmitter.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.93 llvm/utils/TableGen/DAGISelEmitter.cpp:1.94 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.93 Fri Dec 9 19:57:33 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Dec 9 20:36:00 2005 @@ -1900,6 +1900,8 @@ << ResNo << "C, MVT::" << getEnumName(N->getType()) << ");\n"; } else if (!N->isLeaf() && N->getOperator()->getName() == "tglobaladdr") { OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; + } else if (!N->isLeaf() && N->getOperator()->getName() == "tconstpool") { + OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; } else if (N->isLeaf() && (CP = NodeGetComplexPattern(N, ISE))) { std::string Fn = CP->getSelectFunc(); NumRes = CP->getNumOperands(); From alenhar2 at cs.uiuc.edu Sat Dec 10 21:54:43 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Sat, 10 Dec 2005 21:54:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp AlphaInstrInfo.td Message-ID: <200512110354.VAA29201@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelDAGToDAG.cpp updated: 1.15 -> 1.16 AlphaInstrInfo.td updated: 1.82 -> 1.83 --- Log message: FP select improvements (and likely breakage), oh and crazy people might want to *return* floating point values. Don't see why myself --- Diffs of the changes: (+46 -42) AlphaISelDAGToDAG.cpp | 31 +++------------------------ AlphaInstrInfo.td | 57 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 42 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp diff -u llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.15 llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.16 --- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.15 Tue Dec 6 17:27:39 2005 +++ llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Sat Dec 10 21:54:31 2005 @@ -287,6 +287,10 @@ if (N->getOperand(1).getValueType() == MVT::i64) { Chain = CurDAG->getCopyToReg(Chain, Alpha::R0, Val, InFlag); InFlag = Chain.getValue(1); + } else if (N->getOperand(1).getValueType() == MVT::f64 || + N->getOperand(1).getValueType() == MVT::f32) { + Chain = CurDAG->getCopyToReg(Chain, Alpha::F0, Val, InFlag); + InFlag = Chain.getValue(1); } } Chain = CurDAG->getCopyToReg(Chain, Alpha::R26, getRASaveReg(), InFlag); @@ -397,33 +401,6 @@ } break; - case ISD::SELECT: - if (MVT::isFloatingPoint(N->getValueType(0))) { - //move int to fp - bool isDouble = N->getValueType(0) == MVT::f64; - SDOperand LD, - cond = Select(N->getOperand(0)), - TV = Select(N->getOperand(1)), - FV = Select(N->getOperand(2)); - - if (AlphaLowering.hasITOF()) { - LD = CurDAG->getNode(AlphaISD::ITOFT_, MVT::f64, cond); - } else { - int FrameIdx = - CurDAG->getMachineFunction().getFrameInfo()->CreateStackObject(8, 8); - SDOperand FI = CurDAG->getFrameIndex(FrameIdx, MVT::i64); - SDOperand ST = CurDAG->getTargetNode(Alpha::STQ, MVT::Other, - cond, FI, CurDAG->getRegister(Alpha::R31, MVT::i64)); - LD = CurDAG->getTargetNode(Alpha::LDT, MVT::f64, FI, - CurDAG->getRegister(Alpha::R31, MVT::i64), - ST); - } - SDOperand FP = CurDAG->getTargetNode(isDouble?Alpha::FCMOVEQT:Alpha::FCMOVEQS, - MVT::f64, TV, FV, LD); - return FP; - } - break; - } return SelectCode(Op); Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.82 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.83 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.82 Thu Dec 8 18:45:42 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Sat Dec 10 21:54:31 2005 @@ -84,7 +84,6 @@ return build != 0; }], iZAPX>; - def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>; def add4 : PatFrag<(ops node:$op1, node:$op2), (add (shl node:$op1, 2), node:$op2)>; @@ -578,26 +577,54 @@ //TODO: Add lots more FP patterns //conditional moves, floats -let OperandList = (ops F4RC:$RDEST, F4RC:$RSRC2, F4RC:$RSRC, F8RC:$RCOND), +let OperandList = (ops F4RC:$RDEST, F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND), isTwoAddress = 1 in { -def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if = zero -def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if >= zero -def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if > zero -def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if <= zero -def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RSRC,$RDEST",[]>; // FCMOVE if < zero -def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if != zero +def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if = zero +def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if >= zero +def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if > zero +def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if <= zero +def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST",[]>; // FCMOVE if < zero +def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if != zero } //conditional moves, doubles -let OperandList = (ops F8RC:$RDEST, F8RC:$RSRC2, F8RC:$RSRC, F8RC:$RCOND), +let OperandList = (ops F8RC:$RDEST, F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND), isTwoAddress = 1 in { -def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if = zero -def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if >= zero -def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if > zero -def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if <= zero -def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RSRC,$RDEST",[]>; // FCMOVE if < zero -def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if != zero +def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", []>; +def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", []>; +def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST", []>; +def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST", []>; +def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST", []>; +def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", []>; } +//misc FP selects +//Select double +def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), + (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; +def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), + (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; +def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), + (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>; +def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), + (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>; +def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), + (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>; +def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), + (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>; +//Select single +def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), + (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; +def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), + (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; +def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), + (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>; +def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), + (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>; +def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), + (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>; +def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), + (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>; + let OperandList = (ops GPRC:$RC, F4RC:$RA), Fb = 31 in From lattner at cs.uiuc.edu Sun Dec 11 01:37:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 11 Dec 2005 01:37:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Message-ID: <200512110737.BAA03722@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCCodeEmitter.cpp updated: 1.41 -> 1.42 --- Log message: Fix the JIT failures from last night. --- Diffs of the changes: (+2 -1) PPCCodeEmitter.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.41 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.42 --- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.41 Tue Nov 15 18:48:01 2005 +++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Sun Dec 11 01:37:41 2005 @@ -242,11 +242,12 @@ unsigned index = MO.getConstantPoolIndex(); unsigned Opcode = MI.getOpcode(); rv = MCE.getConstantPoolEntryAddress(index); - if (Opcode == PPC::LIS) { + if (Opcode == PPC::LIS || Opcode == PPC::ADDIS) { // lis wants hi16(addr) if ((short)rv < 0) rv += 1 << 16; rv >>= 16; } else if (Opcode == PPC::LWZ || Opcode == PPC::LA || + Opcode == PPC::LI || Opcode == PPC::LFS || Opcode == PPC::LFD) { // These load opcodes want lo16(addr) rv &= 0xffff; From lattner at cs.uiuc.edu Sun Dec 11 01:45:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 11 Dec 2005 01:45:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200512110745.BAA03808@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.17 -> 1.18 --- Log message: Realize the constant pool & global addrs must always be ptr type --- Diffs of the changes: (+6 -5) TargetSelectionDAG.td | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.17 llvm/lib/Target/TargetSelectionDAG.td:1.18 --- llvm/lib/Target/TargetSelectionDAG.td:1.17 Fri Dec 9 20:36:00 2005 +++ llvm/lib/Target/TargetSelectionDAG.td Sun Dec 11 01:45:04 2005 @@ -69,7 +69,8 @@ } // Builtin profiles. -def SDTImm : SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. +def SDTIntLeaf: SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. +def SDTPtrLeaf: SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; // for '&g'. def SDTOther : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'. def SDTUNDEF : SDTypeProfile<1, 0, []>; // for 'undef'. def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc. @@ -165,16 +166,16 @@ def set; def node; -def imm : SDNode<"ISD::Constant" , SDTImm , [], "ConstantSDNode">; +def imm : SDNode<"ISD::Constant" , SDTIntLeaf , [], "ConstantSDNode">; def vt : SDNode<"ISD::VALUETYPE" , SDTOther , [], "VTSDNode">; def bb : SDNode<"ISD::BasicBlock", SDTOther , [], "BasicBlockSDNode">; def cond : SDNode<"ISD::CONDCODE" , SDTOther , [], "CondCodeSDNode">; def undef : SDNode<"ISD::UNDEF" , SDTUNDEF , []>; -def globaladdr : SDNode<"ISD::GlobalAddress", SDTImm, [], +def globaladdr : SDNode<"ISD::GlobalAddress", SDTPtrLeaf, [], "GlobalAddressSDNode">; -def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTImm, [], +def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTPtrLeaf, [], "GlobalAddressSDNode">; -def tconstpool : SDNode<"ISD::TargetConstantPool", SDTImm, [], +def tconstpool : SDNode<"ISD::TargetConstantPool", SDTPtrLeaf, [], "ConstantPoolSDNode">; def add : SDNode<"ISD::ADD" , SDTIntBinOp , [SDNPCommutative, SDNPAssociative]>; From lattner at cs.uiuc.edu Sun Dec 11 01:46:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 11 Dec 2005 01:46:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp PPCInstrInfo.td Message-ID: <200512110746.BAA03867@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.123 -> 1.124 PPCInstrInfo.td updated: 1.154 -> 1.155 --- Log message: Remove type casts that are no longer needed --- Diffs of the changes: (+7 -6) PPCAsmPrinter.cpp | 5 +++-- PPCInstrInfo.td | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.123 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.124 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.123 Fri Dec 9 12:24:29 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Sun Dec 11 01:45:47 2005 @@ -42,7 +42,7 @@ Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); class PPCAsmPrinter : public AsmPrinter { -public: + public: std::set FnStubs, GVStubs, LinkOnceStubs; PPCAsmPrinter(std::ostream &O, TargetMachine &TM) @@ -197,6 +197,7 @@ Data64bitsDirective = 0; // we can't emit a 64-bit unit AlignmentIsInBytes = false; // Alignment is by power of 2. ConstantPoolSection = "\t.const\t"; + LCOMMDirective = "\t.lcomm\t"; } virtual const char *getPassName() const { @@ -465,7 +466,7 @@ SwitchSection(".data", I); if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. if (I->hasInternalLinkage()) - O << ".lcomm " << name << "," << Size << "," << Align; + O << LCOMMDirective << name << "," << Size << "," << Align; else O << ".comm " << name << "," << Size; O << "\t\t; '" << I->getName() << "'\n"; Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.154 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.155 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.154 Fri Dec 9 20:36:00 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Sun Dec 11 01:45:47 2005 @@ -940,10 +940,10 @@ (RLDICL G8RC:$in, (SRL64 imm:$imm), imm:$imm)>; // Hi and Lo for Darwin Global Addresses. -def : Pat<(PPChi tglobaladdr:$in, (i32 0)), (LIS tglobaladdr:$in)>; -def : Pat<(PPClo tglobaladdr:$in, (i32 0)), (LI tglobaladdr:$in)>; -def : Pat<(PPChi tconstpool:$in, (i32 0)), (LIS tconstpool:$in)>; -def : Pat<(PPClo tconstpool:$in, (i32 0)), (LI tconstpool:$in)>; +def : Pat<(PPChi tglobaladdr:$in, 0), (LIS tglobaladdr:$in)>; +def : Pat<(PPClo tglobaladdr:$in, 0), (LI tglobaladdr:$in)>; +def : Pat<(PPChi tconstpool:$in, 0), (LIS tconstpool:$in)>; +def : Pat<(PPClo tconstpool:$in, 0), (LI tconstpool:$in)>; def : Pat<(add GPRC:$in, (PPChi tglobaladdr:$g, 0)), (ADDIS GPRC:$in, tglobaladdr:$g)>; def : Pat<(add GPRC:$in, (PPChi tconstpool:$g, 0)), From lattner at cs.uiuc.edu Sun Dec 11 02:36:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 11 Dec 2005 02:36:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200512110836.CAA15305@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.18 -> 1.19 --- Log message: add selectcc --- Diffs of the changes: (+6 -0) TargetSelectionDAG.td | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.18 llvm/lib/Target/TargetSelectionDAG.td:1.19 --- llvm/lib/Target/TargetSelectionDAG.td:1.18 Sun Dec 11 01:45:04 2005 +++ llvm/lib/Target/TargetSelectionDAG.td Sun Dec 11 02:35:54 2005 @@ -119,6 +119,11 @@ SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3> ]>; +def SDTSelectCC : SDTypeProvile<1, 5, [ // select_cc + SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisSameAs<0, 3>, + SDTCisVT<5, OtherVT> +]>; + def SDTBr : SDTypeProfile<0, 1, [ // br SDTCisVT<0, OtherVT> ]>; @@ -226,6 +231,7 @@ def setcc : SDNode<"ISD::SETCC" , SDTSetCC>; def select : SDNode<"ISD::SELECT" , SDTSelect>; +def selectcc : SDNode<"ISD::SELECT_CC" , SDTSelectCC>; def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>; def brcond : SDNode<"ISD::BRCOND" , SDTBrCond, [SDNPHasChain]>; From lattner at cs.uiuc.edu Sun Dec 11 03:05:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 11 Dec 2005 03:05:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200512110905.DAA18374@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.113 -> 1.114 --- Log message: Minor tweak to get isel opt --- Diffs of the changes: (+2 -1) SelectionDAGISel.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.113 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.114 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.113 Thu Dec 8 02:00:12 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sun Dec 11 03:05:13 2005 @@ -1324,7 +1324,8 @@ break; } } - if (!hasConstantIndex) return; + // If this is a GEP &Alloca, 0, 0, forward subst the frame index into uses. + if (!hasConstantIndex && !isa(GEPI->getOperand(0))) return; // Otherwise, decompose the GEP instruction into multiplies and adds. Sum the // constant offset (which we now know is non-zero) and deal with it later. From lattner at cs.uiuc.edu Sun Dec 11 12:43:24 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 11 Dec 2005 12:43:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200512111843.MAA17295@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.19 -> 1.20 --- Log message: Fix typo :( --- Diffs of the changes: (+1 -1) TargetSelectionDAG.td | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.19 llvm/lib/Target/TargetSelectionDAG.td:1.20 --- llvm/lib/Target/TargetSelectionDAG.td:1.19 Sun Dec 11 02:35:54 2005 +++ llvm/lib/Target/TargetSelectionDAG.td Sun Dec 11 12:43:13 2005 @@ -119,7 +119,7 @@ SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3> ]>; -def SDTSelectCC : SDTypeProvile<1, 5, [ // select_cc +def SDTSelectCC : SDTypeProfile<1, 5, [ // select_cc SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisSameAs<0, 3>, SDTCisVT<5, OtherVT> ]>; From lattner at cs.uiuc.edu Sun Dec 11 13:55:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 11 Dec 2005 13:55:55 -0600 Subject: [llvm-commits] CVS: llvm/utils/NightlyTest.pl Message-ID: <200512111955.NAA14546@zion.cs.uiuc.edu> Changes in directory llvm/utils: NightlyTest.pl updated: 1.100 -> 1.101 --- Log message: Send an indicator to llvm-testresults if the build failed --- Diffs of the changes: (+1 -1) NightlyTest.pl | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/NightlyTest.pl diff -u llvm/utils/NightlyTest.pl:1.100 llvm/utils/NightlyTest.pl:1.101 --- llvm/utils/NightlyTest.pl:1.100 Tue Nov 1 11:59:42 2005 +++ llvm/utils/NightlyTest.pl Sun Dec 11 13:55:39 2005 @@ -462,7 +462,7 @@ $BuildStatus = "

error: compilation " . "aborted

"; $BuildError = 1; - if ($VERBOSE) { print "BUILD ERROR\n"; } + print "\n***ERROR BUILDING TREE\n\n"; } if ($BuildError) { $NODEJAGNU=1; }