From lattner at cs.uiuc.edu Mon Oct 10 01:00:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 10 Oct 2005 01:00:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Target.td Message-ID: <200510100600.BAA13149@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td added (r1.1) Target.td updated: 1.51 -> 1.52 --- Log message: Pull DAG ISel generation nodes out of the PowerPC backend to where they can be used by other targets. For those targets that want to use it, have at. :) --- Diffs of the changes: (+216 -89) Target.td | 91 --------------------- TargetSelectionDAG.td | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 216 insertions(+), 89 deletions(-) Index: llvm/lib/Target/TargetSelectionDAG.td diff -c /dev/null llvm/lib/Target/TargetSelectionDAG.td:1.1 *** /dev/null Mon Oct 10 01:00:40 2005 --- llvm/lib/Target/TargetSelectionDAG.td Mon Oct 10 01:00:30 2005 *************** *** 0 **** --- 1,214 ---- + //===- TargetSelectionDAG.td - Common code for DAG isels ---*- tablegen -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines the target-independent interfaces used by SelectionDAG + // instruction selection generators. + // + //===----------------------------------------------------------------------===// + + //===----------------------------------------------------------------------===// + // Selection DAG Type Constraint definitions. + // + // Note that the semantics of these constraints are hard coded into tblgen. To + // modify or add constraints, you have to hack tblgen. + // + + class SDTypeConstraint { + int OperandNum = opnum; + } + + // SDTCisVT - The specified operand has exactly this VT. + class SDTCisVT : SDTypeConstraint { + ValueType VT = vt; + } + + // SDTCisInt - The specified operand is has integer type. + class SDTCisInt : SDTypeConstraint; + + // SDTCisFP - The specified operand is has floating point type. + class SDTCisFP : SDTypeConstraint; + + // SDTCisSameAs - The two specified operands have identical types. + class SDTCisSameAs : SDTypeConstraint { + int OtherOperandNum = OtherOp; + } + + // SDTCisVTSmallerThanOp - The specified operand is a VT SDNode, and its type is + // smaller than the 'Other' operand. + class SDTCisVTSmallerThanOp : SDTypeConstraint { + int OtherOperandNum = OtherOp; + } + + //===----------------------------------------------------------------------===// + // Selection DAG Type Profile definitions. + // + // These use the constraints defined above to describe the type requirements of + // the various nodes. These are not hard coded into tblgen, allowing targets to + // add their own if needed. + // + + // SDTypeProfile - This profile describes the type requirements of a Selection + // DAG node. + class SDTypeProfile constraints> { + int NumResults = numresults; + int NumOperands = numoperands; + list Constraints = constraints; + } + + // Builtin profiles. + def SDTImm : SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. + def SDTVT : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt' + def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc. + SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0> + ]>; + def SDTFPBinOp : SDTypeProfile<1, 2, [ // fadd, fmul, etc. + SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0> + ]>; + def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz + SDTCisSameAs<0, 1>, SDTCisInt<0> + ]>; + def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc + SDTCisSameAs<0, 1>, SDTCisFP<0> + ]>; + def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg + SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>, + SDTCisVTSmallerThanOp<2, 1> + ]>; + + //===----------------------------------------------------------------------===// + // Selection DAG Node Properties. + // + // Note: These are hard coded into tblgen. + // + class SDNodeProperty; + def SDNPCommutative : SDNodeProperty; // X op Y == Y op X + def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z) + + //===----------------------------------------------------------------------===// + // Selection DAG Node definitions. + // + class SDNode props = [], string sdclass = "SDNode"> { + string Opcode = opcode; + string SDClass = sdclass; + list Properties = props; + SDTypeProfile TypeProfile = typeprof; + } + + def set; + def node; + + def imm : SDNode<"ISD::Constant" , SDTImm , [], "ConstantSDNode">; + def vt : SDNode<"ISD::VALUETYPE" , SDTVT , [], "VTSDNode">; + def add : SDNode<"ISD::ADD" , SDTIntBinOp , + [SDNPCommutative, SDNPAssociative]>; + def sub : SDNode<"ISD::SUB" , SDTIntBinOp>; + def mul : SDNode<"ISD::MUL" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; + def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp, [SDNPCommutative]>; + def mulhu : SDNode<"ISD::MULHU" , SDTIntBinOp, [SDNPCommutative]>; + def sdiv : SDNode<"ISD::SDIV" , SDTIntBinOp>; + def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; + def srem : SDNode<"ISD::SREM" , SDTIntBinOp>; + def urem : SDNode<"ISD::UREM" , SDTIntBinOp>; + def srl : SDNode<"ISD::SRL" , SDTIntBinOp>; + def sra : SDNode<"ISD::SRA" , SDTIntBinOp>; + def shl : SDNode<"ISD::SHL" , SDTIntBinOp>; + def and : SDNode<"ISD::AND" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; + def or : SDNode<"ISD::OR" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; + def xor : SDNode<"ISD::XOR" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; + def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>; + def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>; + def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; + def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>; + def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; + def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; + def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; + def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; + + def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; + def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; + + //===----------------------------------------------------------------------===// + // Selection DAG Node Transformation Functions. + // + // This mechanism allows targets to manipulate nodes in the output DAG once a + // match has been formed. This is typically used to manipulate immediate + // values. + // + class SDNodeXForm { + SDNode Opcode = opc; + code XFormFunction = xformFunction; + } + + def NOOP_SDNodeXForm : SDNodeXForm; + + + //===----------------------------------------------------------------------===// + // Selection DAG Pattern Fragments. + // + // Pattern fragments are reusable chunks of dags that match specific things. + // They can take arguments and have C++ predicates that control whether they + // match. They are intended to make the patterns for common instructions more + // compact and readable. + // + + /// PatFrag - Represents a pattern fragment. This can match something on the + /// DAG, frame a single node to multiply nested other fragments. + /// + class PatFrag { + dag Operands = ops; + dag Fragment = frag; + code Predicate = pred; + SDNodeXForm OperandTransform = xform; + } + + // PatLeaf's are pattern fragments that have no operands. This is just a helper + // to define immediates and other common things concisely. + class PatLeaf + : PatFrag<(ops), frag, pred, xform>; + + // Leaf fragments. + + def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>; + def immZero : PatLeaf<(imm), [{ return N->isNullValue(); }]>; + + def vtInt : PatLeaf<(vt), [{ return MVT::isInteger(N->getVT()); }]>; + def vtFP : PatLeaf<(vt), [{ return MVT::isFloatingPoint(N->getVT()); }]>; + + // Other helper fragments. + + def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>; + def ineg : PatFrag<(ops node:$in), (sub immZero, node:$in)>; + + //===----------------------------------------------------------------------===// + // Selection DAG Pattern Support. + // + // Patterns are what are actually matched against the target-flavored + // instruction selection DAG. Instructions defined by the target implicitly + // define patterns in most cases, but patterns can also be explicitly added when + // an operation is defined by a sequence of instructions (e.g. loading a large + // immediate value on RISC targets that do not support immediates as large as + // their GPRs). + // + + class Pattern resultInstrs> { + dag PatternToMatch = patternToMatch; + list ResultInstrs = resultInstrs; + } + + // Pat - A simple (but common) form of a pattern, which produces a simple result + // not needing a full list. + class Pat : Pattern; + Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.51 llvm/lib/Target/Target.td:1.52 --- llvm/lib/Target/Target.td:1.51 Tue Oct 4 00:09:20 2005 +++ llvm/lib/Target/Target.td Mon Oct 10 01:00:30 2005 @@ -241,94 +241,7 @@ list AssemblyWriters = [DefaultAsmWriter]; } - //===----------------------------------------------------------------------===// -// DAG node definitions used by the instruction selector. +// Pull in the common support for DAG isel generation // -// NOTE: all of this is a work-in-progress and should be ignored for now. -// -/* -class Expander result> { - dag Pattern = pattern; - list Result = result; -} - -class DagNodeValType; -def DNVT_any : DagNodeValType; // No constraint on tree node -def DNVT_void : DagNodeValType; // Tree node always returns void -def DNVT_val : DagNodeValType; // A non-void type -def DNVT_arg0 : DagNodeValType; // Tree node returns same type as Arg0 -def DNVT_arg1 : DagNodeValType; // Tree node returns same type as Arg1 -def DNVT_ptr : DagNodeValType; // The target pointer type -def DNVT_i8 : DagNodeValType; // Always have an i8 value - -class DagNode args> { - DagNodeValType RetType = ret; - list ArgTypes = args; - string EnumName = ?; -} - -// BuiltinDagNodes are built into the instruction selector and correspond to -// enum values. -class BuiltinDagNode Args, - string Ename> : DagNode { - let EnumName = Ename; -} - -// Magic nodes... -def Void : RegisterClass { let isDummyClass = 1; } -def set : DagNode; -def chain : BuiltinDagNode; -def blockchain : BuiltinDagNode; -def ChainExpander : Expander<(chain Void, Void), []>; -def BlockChainExpander : Expander<(blockchain Void, Void), []>; - - -// Terminals... -def imm : BuiltinDagNode; -def frameidx : BuiltinDagNode; -def basicblock : BuiltinDagNode; - -// Arithmetic... -def plus : BuiltinDagNode; -def minus : BuiltinDagNode; -def times : BuiltinDagNode; -def sdiv : BuiltinDagNode; -def udiv : BuiltinDagNode; -def srem : BuiltinDagNode; -def urem : BuiltinDagNode; -def and : BuiltinDagNode; -def or : BuiltinDagNode; -def xor : BuiltinDagNode; - -// Comparisons... -def seteq : BuiltinDagNode; -def setne : BuiltinDagNode; -def setlt : BuiltinDagNode; -def setle : BuiltinDagNode; -def setgt : BuiltinDagNode; -def setge : BuiltinDagNode; - -def load : BuiltinDagNode; -//def store : BuiltinDagNode; - -// Other... -def ret : BuiltinDagNode; -def retvoid : BuiltinDagNode; -def br : BuiltinDagNode; -def brcond : BuiltinDagNode; - -def unspec1 : BuiltinDagNode; -def unspec2 : BuiltinDagNode; - -//===----------------------------------------------------------------------===// -// DAG nonterminals definitions used by the instruction selector... -// -class Nonterminal { - dag Pattern = pattern; - bit BuiltIn = 0; -} - -*/ +include "../TargetSelectionDAG.td" From lattner at cs.uiuc.edu Mon Oct 10 01:01:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 10 Oct 2005 01:01:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200510100601.BAA13189@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.118 -> 1.119 --- Log message: These definitions have been moved to common code. --- Diffs of the changes: (+0 -199) PowerPCInstrInfo.td | 199 ---------------------------------------------------- 1 files changed, 199 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.118 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.119 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.118 Sun Oct 2 02:46:28 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Mon Oct 10 01:01:00 2005 @@ -14,205 +14,6 @@ include "PowerPCInstrFormats.td" -//===----------------------------------------------------------------------===// -// Selection DAG Type Constraint definitions. -// -// Note that the semantics of these constraints are hard coded into tblgen. To -// modify or add constraints, you have to hack tblgen. -// - -class SDTypeConstraint { - int OperandNum = opnum; -} - -// SDTCisVT - The specified operand has exactly this VT. -class SDTCisVT : SDTypeConstraint { - ValueType VT = vt; -} - -// SDTCisInt - The specified operand is has integer type. -class SDTCisInt : SDTypeConstraint; - -// SDTCisFP - The specified operand is has floating point type. -class SDTCisFP : SDTypeConstraint; - -// SDTCisSameAs - The two specified operands have identical types. -class SDTCisSameAs : SDTypeConstraint { - int OtherOperandNum = OtherOp; -} - -// SDTCisVTSmallerThanOp - The specified operand is a VT SDNode, and its type is -// smaller than the 'Other' operand. -class SDTCisVTSmallerThanOp : SDTypeConstraint { - int OtherOperandNum = OtherOp; -} - -//===----------------------------------------------------------------------===// -// Selection DAG Type Profile definitions. -// -// These use the constraints defined above to describe the type requirements of -// the various nodes. These are not hard coded into tblgen, allowing targets to -// add their own if needed. -// - -// SDTypeProfile - This profile describes the type requirements of a Selection -// DAG node. -class SDTypeProfile constraints> { - int NumResults = numresults; - int NumOperands = numoperands; - list Constraints = constraints; -} - -// Builtin profiles. -def SDTImm : SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. -def SDTVT : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt' -def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc. - SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0> -]>; -def SDTFPBinOp : SDTypeProfile<1, 2, [ // fadd, fmul, etc. - SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0> -]>; -def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz - SDTCisSameAs<0, 1>, SDTCisInt<0> -]>; -def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc - SDTCisSameAs<0, 1>, SDTCisFP<0> -]>; -def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg - SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>, - SDTCisVTSmallerThanOp<2, 1> -]>; - -//===----------------------------------------------------------------------===// -// Selection DAG Node Properties. -// -// Note: These are hard coded into tblgen. -// -class SDNodeProperty; -def SDNPCommutative : SDNodeProperty; // X op Y == Y op X -def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z) - -//===----------------------------------------------------------------------===// -// Selection DAG Node definitions. -// -class SDNode props = [], string sdclass = "SDNode"> { - string Opcode = opcode; - string SDClass = sdclass; - list Properties = props; - SDTypeProfile TypeProfile = typeprof; -} - -def set; -def node; - -def imm : SDNode<"ISD::Constant" , SDTImm , [], "ConstantSDNode">; -def vt : SDNode<"ISD::VALUETYPE" , SDTVT , [], "VTSDNode">; -def add : SDNode<"ISD::ADD" , SDTIntBinOp , - [SDNPCommutative, SDNPAssociative]>; -def sub : SDNode<"ISD::SUB" , SDTIntBinOp>; -def mul : SDNode<"ISD::MUL" , SDTIntBinOp, - [SDNPCommutative, SDNPAssociative]>; -def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp, [SDNPCommutative]>; -def mulhu : SDNode<"ISD::MULHU" , SDTIntBinOp, [SDNPCommutative]>; -def sdiv : SDNode<"ISD::SDIV" , SDTIntBinOp>; -def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; -def srem : SDNode<"ISD::SREM" , SDTIntBinOp>; -def urem : SDNode<"ISD::UREM" , SDTIntBinOp>; -def srl : SDNode<"ISD::SRL" , SDTIntBinOp>; -def sra : SDNode<"ISD::SRA" , SDTIntBinOp>; -def shl : SDNode<"ISD::SHL" , SDTIntBinOp>; -def and : SDNode<"ISD::AND" , SDTIntBinOp, - [SDNPCommutative, SDNPAssociative]>; -def or : SDNode<"ISD::OR" , SDTIntBinOp, - [SDNPCommutative, SDNPAssociative]>; -def xor : SDNode<"ISD::XOR" , SDTIntBinOp, - [SDNPCommutative, SDNPAssociative]>; -def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>; -def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>; -def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; -def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>; -def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; -def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; -def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; -def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; - -def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; -def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; - -//===----------------------------------------------------------------------===// -// Selection DAG Node Transformation Functions. -// -// This mechanism allows targets to manipulate nodes in the output DAG once a -// match has been formed. This is typically used to manipulate immediate -// values. -// -class SDNodeXForm { - SDNode Opcode = opc; - code XFormFunction = xformFunction; -} - -def NOOP_SDNodeXForm : SDNodeXForm; - - -//===----------------------------------------------------------------------===// -// Selection DAG Pattern Fragments. -// -// Pattern fragments are reusable chunks of dags that match specific things. -// They can take arguments and have C++ predicates that control whether they -// match. They are intended to make the patterns for common instructions more -// compact and readable. -// - -/// PatFrag - Represents a pattern fragment. This can match something on the -/// DAG, frame a single node to multiply nested other fragments. -/// -class PatFrag { - dag Operands = ops; - dag Fragment = frag; - code Predicate = pred; - SDNodeXForm OperandTransform = xform; -} - -// PatLeaf's are pattern fragments that have no operands. This is just a helper -// to define immediates and other common things concisely. -class PatLeaf - : PatFrag<(ops), frag, pred, xform>; - -// Leaf fragments. - -def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>; -def immZero : PatLeaf<(imm), [{ return N->isNullValue(); }]>; - -def vtInt : PatLeaf<(vt), [{ return MVT::isInteger(N->getVT()); }]>; -def vtFP : PatLeaf<(vt), [{ return MVT::isFloatingPoint(N->getVT()); }]>; - -// Other helper fragments. - -def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>; -def ineg : PatFrag<(ops node:$in), (sub immZero, node:$in)>; - -//===----------------------------------------------------------------------===// -// Selection DAG Pattern Support. -// -// Patterns are what are actually matched against the target-flavored -// instruction selection DAG. Instructions defined by the target implicitly -// define patterns in most cases, but patterns can also be explicitly added when -// an operation is defined by a sequence of instructions (e.g. loading a large -// immediate value on RISC targets that do not support immediates as large as -// their GPRs). -// - -class Pattern resultInstrs> { - dag PatternToMatch = patternToMatch; - list ResultInstrs = resultInstrs; -} - -// Pat - A simple (but common) form of a pattern, which produces a simple result -// not needing a full list. -class Pat : Pattern; //===----------------------------------------------------------------------===// // PowerPC specific transformation functions and pattern fragments. From lattner at cs.uiuc.edu Mon Oct 10 11:47:22 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 10 Oct 2005 11:47:22 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp SelectionDAGISel.cpp Message-ID: <200510101647.LAA14262@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.203 -> 1.204 SelectionDAGISel.cpp updated: 1.87 -> 1.88 --- Log message: Enable Nate's excellent DAG combiner work by default. This allows the removal of a bunch of ad-hoc and crufty code from SelectionDAG.cpp. --- Diffs of the changes: (+18 -558) SelectionDAG.cpp | 556 +-------------------------------------------------- SelectionDAGISel.cpp | 20 - 2 files changed, 18 insertions(+), 558 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.203 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.204 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.203 Sun Oct 9 17:09:50 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Oct 10 11:47:10 2005 @@ -27,11 +27,6 @@ #include using namespace llvm; -// Temporary boolean for testing the dag combiner -namespace llvm { - extern bool CombinerEnabled; -} - static bool isCommutativeBinOp(unsigned Opcode) { switch (Opcode) { case ISD::ADD: @@ -643,6 +638,20 @@ return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI); } return false; + case ISD::ADD: + // (add X, Y) & C == 0 iff (X&C)|(Y&C) == 0 and all bits are low bits. + if ((Mask&(Mask+1)) == 0) { // All low bits + if (MaskedValueIsZero(Op.getOperand(0), Mask, TLI) && + MaskedValueIsZero(Op.getOperand(1), Mask, TLI)) { + std::cerr << "MASK: "; + Op.getOperand(0).Val->dump(); + std::cerr << " - "; + Op.getOperand(1).Val->dump(); + std::cerr << "\n"; + return true; + } + } + break; case ISD::SUB: if (ConstantSDNode *CLHS = dyn_cast(Op.getOperand(0))) { // We know that the top bits of C-X are clear if X contains less bits @@ -876,133 +885,6 @@ return getSetCC(VT, N2, N1, ISD::getSetCCSwappedOperands(Cond)); } - if (!CombinerEnabled) { - if (N1 == N2) { - // We can always fold X == Y for integer setcc's. - if (MVT::isInteger(N1.getValueType())) - return getConstant(ISD::isTrueWhenEqual(Cond), VT); - unsigned UOF = ISD::getUnorderedFlavor(Cond); - if (UOF == 2) // FP operators that are undefined on NaNs. - return getConstant(ISD::isTrueWhenEqual(Cond), VT); - if (UOF == unsigned(ISD::isTrueWhenEqual(Cond))) - return getConstant(UOF, VT); - // Otherwise, we can't fold it. However, we can simplify it to SETUO/SETO - // if it is not already. - ISD::CondCode NewCond = UOF == 0 ? ISD::SETUO : ISD::SETO; - if (NewCond != Cond) - return getSetCC(VT, N1, N2, NewCond); - } - - if (Cond == ISD::SETEQ || Cond == ISD::SETNE) { - if (N1.getOpcode() == ISD::ADD || N1.getOpcode() == ISD::SUB || - N1.getOpcode() == ISD::XOR) { - // Simplify (X+Y) == (X+Z) --> Y == Z - if (N1.getOpcode() == N2.getOpcode()) { - if (N1.getOperand(0) == N2.getOperand(0)) - return getSetCC(VT, N1.getOperand(1), N2.getOperand(1), Cond); - if (N1.getOperand(1) == N2.getOperand(1)) - return getSetCC(VT, N1.getOperand(0), N2.getOperand(0), Cond); - if (isCommutativeBinOp(N1.getOpcode())) { - // If X op Y == Y op X, try other combinations. - if (N1.getOperand(0) == N2.getOperand(1)) - return getSetCC(VT, N1.getOperand(1), N2.getOperand(0), Cond); - if (N1.getOperand(1) == N2.getOperand(0)) - return getSetCC(VT, N1.getOperand(1), N2.getOperand(1), Cond); - } - } - - // FIXME: move this stuff to the DAG Combiner when it exists! - - // Turn (X^C1) == C2 into X == C1^C2 iff X&~C1 = 0. Common for condcodes. - if (N1.getOpcode() == ISD::XOR) - if (ConstantSDNode *XORC = dyn_cast(N1.getOperand(1))) - if (ConstantSDNode *RHSC = dyn_cast(N2)) { - // If we know that all of the inverted bits are zero, don't bother - // performing the inversion. - if (MaskedValueIsZero(N1.getOperand(0), ~XORC->getValue(), TLI)) - return getSetCC(VT, N1.getOperand(0), - getConstant(XORC->getValue()^RHSC->getValue(), - N1.getValueType()), Cond); - } - - // Simplify (X+Z) == X --> Z == 0 - if (N1.getOperand(0) == N2) - return getSetCC(VT, N1.getOperand(1), - getConstant(0, N1.getValueType()), Cond); - if (N1.getOperand(1) == N2) { - if (isCommutativeBinOp(N1.getOpcode())) - return getSetCC(VT, N1.getOperand(0), - getConstant(0, N1.getValueType()), Cond); - else { - assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!"); - // (Z-X) == X --> Z == X<<1 - return getSetCC(VT, N1.getOperand(0), - getNode(ISD::SHL, N2.getValueType(), - N2, getConstant(1, TLI.getShiftAmountTy())), - Cond); - } - } - } - - if (N2.getOpcode() == ISD::ADD || N2.getOpcode() == ISD::SUB || - N2.getOpcode() == ISD::XOR) { - // Simplify X == (X+Z) --> Z == 0 - if (N2.getOperand(0) == N1) { - return getSetCC(VT, N2.getOperand(1), - getConstant(0, N2.getValueType()), Cond); - } else if (N2.getOperand(1) == N1) { - if (isCommutativeBinOp(N2.getOpcode())) { - return getSetCC(VT, N2.getOperand(0), - getConstant(0, N2.getValueType()), Cond); - } else { - assert(N2.getOpcode() == ISD::SUB && "Unexpected operation!"); - // X == (Z-X) --> X<<1 == Z - return getSetCC(VT, getNode(ISD::SHL, N2.getValueType(), N1, - getConstant(1, TLI.getShiftAmountTy())), - N2.getOperand(0), Cond); - } - } - } - } - - // Fold away ALL boolean setcc's. - if (N1.getValueType() == MVT::i1) { - switch (Cond) { - default: assert(0 && "Unknown integer setcc!"); - case ISD::SETEQ: // X == Y -> (X^Y)^1 - N1 = getNode(ISD::XOR, MVT::i1, - getNode(ISD::XOR, MVT::i1, N1, N2), - getConstant(1, MVT::i1)); - break; - case ISD::SETNE: // X != Y --> (X^Y) - N1 = getNode(ISD::XOR, MVT::i1, N1, N2); - break; - case ISD::SETGT: // X >s Y --> X == 0 & Y == 1 --> X^1 & Y - case ISD::SETULT: // X X == 0 & Y == 1 --> X^1 & Y - N1 = getNode(ISD::AND, MVT::i1, N2, - getNode(ISD::XOR, MVT::i1, N1, getConstant(1, MVT::i1))); - break; - case ISD::SETLT: // X X == 1 & Y == 0 --> Y^1 & X - case ISD::SETUGT: // X >u Y --> X == 1 & Y == 0 --> Y^1 & X - N1 = getNode(ISD::AND, MVT::i1, N1, - getNode(ISD::XOR, MVT::i1, N2, getConstant(1, MVT::i1))); - break; - case ISD::SETULE: // X <=u Y --> X == 0 | Y == 1 --> X^1 | Y - case ISD::SETGE: // X >=s Y --> X == 0 | Y == 1 --> X^1 | Y - N1 = getNode(ISD::OR, MVT::i1, N2, - getNode(ISD::XOR, MVT::i1, N1, getConstant(1, MVT::i1))); - break; - case ISD::SETUGE: // X >=u Y --> X == 1 | Y == 0 --> Y^1 | X - case ISD::SETLE: // X <=s Y --> X == 1 | Y == 0 --> Y^1 | X - N1 = getNode(ISD::OR, MVT::i1, N1, - getNode(ISD::XOR, MVT::i1, N2, getConstant(1, MVT::i1))); - break; - } - if (VT != MVT::i1) - N1 = getNode(ISD::ZERO_EXTEND, VT, N1); - return N1; - } - } // Could not fold it. return SDOperand(); } @@ -1337,204 +1219,6 @@ std::swap(N1, N2); } } - - if (!CombinerEnabled) { - switch (Opcode) { - default: break; - case ISD::SHL: // shl 0, X -> 0 - if (N1C->isNullValue()) return N1; - break; - case ISD::SRL: // srl 0, X -> 0 - if (N1C->isNullValue()) return N1; - break; - case ISD::SRA: // sra -1, X -> -1 - if (N1C->isAllOnesValue()) return N1; - break; - case ISD::SIGN_EXTEND_INREG: // SIGN_EXTEND_INREG N1C, EVT - // Extending a constant? Just return the extended constant. - SDOperand Tmp = getNode(ISD::TRUNCATE, cast(N2)->getVT(), N1); - return getNode(ISD::SIGN_EXTEND, VT, Tmp); - } - } - } - - if (!CombinerEnabled) { - if (N2C) { - uint64_t C2 = N2C->getValue(); - - switch (Opcode) { - case ISD::ADD: - if (!C2) return N1; // add X, 0 -> X - break; - case ISD::SUB: - if (!C2) return N1; // sub X, 0 -> X - return getNode(ISD::ADD, VT, N1, getConstant(-C2, VT)); - case ISD::MUL: - if (!C2) return N2; // mul X, 0 -> 0 - if (N2C->isAllOnesValue()) // mul X, -1 -> 0-X - return getNode(ISD::SUB, VT, getConstant(0, VT), N1); - - // FIXME: Move this to the DAG combiner when it exists. - if ((C2 & C2-1) == 0) { - SDOperand ShAmt = getConstant(Log2_64(C2), TLI.getShiftAmountTy()); - return getNode(ISD::SHL, VT, N1, ShAmt); - } - break; - - case ISD::MULHU: - case ISD::MULHS: - if (!C2) return N2; // mul X, 0 -> 0 - - if (C2 == 1) // 0X*01 -> 0X hi(0X) == 0 - return getConstant(0, VT); - - // Many others could be handled here, including -1, powers of 2, etc. - break; - - case ISD::UDIV: - // FIXME: Move this to the DAG combiner when it exists. - if ((C2 & C2-1) == 0 && C2) { - SDOperand ShAmt = getConstant(Log2_64(C2), TLI.getShiftAmountTy()); - return getNode(ISD::SRL, VT, N1, ShAmt); - } - break; - - case ISD::SHL: - case ISD::SRL: - case ISD::SRA: - // If the shift amount is bigger than the size of the data, then all the - // bits are shifted out. Simplify to undef. - if (C2 >= MVT::getSizeInBits(N1.getValueType())) { - return getNode(ISD::UNDEF, N1.getValueType()); - } - if (C2 == 0) return N1; - - if (Opcode == ISD::SRA) { - // If the sign bit is known to be zero, switch this to a SRL. - if (MaskedValueIsZero(N1, - 1ULL << (MVT::getSizeInBits(N1.getValueType())-1), - TLI)) - return getNode(ISD::SRL, N1.getValueType(), N1, N2); - } else { - // If the part left over is known to be zero, the whole thing is zero. - uint64_t TypeMask = ~0ULL >> (64-MVT::getSizeInBits(N1.getValueType())); - if (Opcode == ISD::SRL) { - if (MaskedValueIsZero(N1, TypeMask << C2, TLI)) - return getConstant(0, N1.getValueType()); - } else if (Opcode == ISD::SHL) { - if (MaskedValueIsZero(N1, TypeMask >> C2, TLI)) - return getConstant(0, N1.getValueType()); - } - } - - if (Opcode == ISD::SHL && N1.getNumOperands() == 2) - if (ConstantSDNode *OpSA = dyn_cast(N1.getOperand(1))) { - unsigned OpSAC = OpSA->getValue(); - if (N1.getOpcode() == ISD::SHL) { - if (C2+OpSAC >= MVT::getSizeInBits(N1.getValueType())) - return getConstant(0, N1.getValueType()); - return getNode(ISD::SHL, N1.getValueType(), N1.getOperand(0), - getConstant(C2+OpSAC, N2.getValueType())); - } else if (N1.getOpcode() == ISD::SRL) { - // (X >> C1) << C2: if C2 > C1, ((X & ~0< OpSAC) { - return getNode(ISD::SHL, VT, Mask, - getConstant(C2-OpSAC, N2.getValueType())); - } else { - // (X >> C1) << C2: if C2 <= C1, ((X & ~0<> C1-C2) - return getNode(ISD::SRL, VT, Mask, - getConstant(OpSAC-C2, N2.getValueType())); - } - } else if (N1.getOpcode() == ISD::SRA) { - // if C1 == C2, just mask out low bits. - if (C2 == OpSAC) - return getNode(ISD::AND, VT, N1.getOperand(0), - getConstant(~0ULL << C2, VT)); - } - } - break; - - case ISD::AND: - if (!C2) return N2; // X and 0 -> 0 - if (N2C->isAllOnesValue()) - return N1; // X and -1 -> X - - if (MaskedValueIsZero(N1, C2, TLI)) // X and 0 -> 0 - return getConstant(0, VT); - - { - uint64_t NotC2 = ~C2; - if (VT != MVT::i64) - NotC2 &= (1ULL << MVT::getSizeInBits(VT))-1; - - if (MaskedValueIsZero(N1, NotC2, TLI)) - return N1; // if (X & ~C2) -> 0, the and is redundant - } - - // FIXME: Should add a corresponding version of this for - // ZERO_EXTEND/SIGN_EXTEND by converting them to an ANY_EXTEND node which - // we don't have yet. - // FIXME: NOW WE DO, add this. - - // and (sign_extend_inreg x:16:32), 1 -> and x, 1 - if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG) { - // If we are masking out the part of our input that was extended, just - // mask the input to the extension directly. - unsigned ExtendBits = - MVT::getSizeInBits(cast(N1.getOperand(1))->getVT()); - if ((C2 & (~0ULL << ExtendBits)) == 0) - return getNode(ISD::AND, VT, N1.getOperand(0), N2); - } else if (N1.getOpcode() == ISD::OR) { - if (ConstantSDNode *ORI = dyn_cast(N1.getOperand(1))) - if ((ORI->getValue() & C2) == C2) { - // If the 'or' is setting all of the bits that we are masking for, - // we know the result of the AND will be the AND mask itself. - return N2; - } - } - break; - case ISD::OR: - if (!C2)return N1; // X or 0 -> X - if (N2C->isAllOnesValue()) - return N2; // X or -1 -> -1 - break; - case ISD::XOR: - if (!C2) return N1; // X xor 0 -> X - if (N2C->getValue() == 1 && N1.Val->getOpcode() == ISD::SETCC) { - SDNode *SetCC = N1.Val; - // !(X op Y) -> (X !op Y) - bool isInteger = MVT::isInteger(SetCC->getOperand(0).getValueType()); - ISD::CondCode CC = cast(SetCC->getOperand(2))->get(); - return getSetCC(SetCC->getValueType(0), - SetCC->getOperand(0), SetCC->getOperand(1), - ISD::getSetCCInverse(CC, isInteger)); - } else if (N2C->isAllOnesValue()) { - if (N1.getOpcode() == ISD::AND || N1.getOpcode() == ISD::OR) { - SDNode *Op = N1.Val; - // !(X or Y) -> (!X and !Y) iff X or Y are freely invertible - // !(X and Y) -> (!X or !Y) iff X or Y are freely invertible - SDOperand LHS = Op->getOperand(0), RHS = Op->getOperand(1); - if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) { - LHS = getNode(ISD::XOR, VT, LHS, N2); // RHS = ~LHS - RHS = getNode(ISD::XOR, VT, RHS, N2); // RHS = ~RHS - if (Op->getOpcode() == ISD::AND) - return getNode(ISD::OR, VT, LHS, RHS); - return getNode(ISD::AND, VT, LHS, RHS); - } - } - // X xor -1 -> not(x) ? - } - break; - } - - // Reassociate ((X op C1) op C2) if possible. - if (N1.getOpcode() == Opcode && isAssociativeBinOp(Opcode)) - if (ConstantSDNode *N3C = dyn_cast(N1.Val->getOperand(1))) - return getNode(Opcode, VT, N1.Val->getOperand(0), - getNode(Opcode, VT, N2, N1.Val->getOperand(1))); - } } ConstantFPSDNode *N1CFP = dyn_cast(N1.Val); @@ -1560,180 +1244,16 @@ std::swap(N1, N2); } } - - if (!CombinerEnabled) { - if (Opcode == ISD::FP_ROUND_INREG) - return getNode(ISD::FP_EXTEND, VT, - getNode(ISD::FP_ROUND, cast(N2)->getVT(), N1)); - } } // Finally, fold operations that do not require constants. switch (Opcode) { - case ISD::TokenFactor: - if (!CombinerEnabled) { - if (N1.getOpcode() == ISD::EntryToken) - return N2; - if (N2.getOpcode() == ISD::EntryToken) - return N1; - } - break; - case ISD::SDIV: { - if (CombinerEnabled) break; - - // If we know the sign bits of both operands are zero, strength reduce to a - // udiv instead. Handles (X&15) /s 4 -> X&15 >> 2 - uint64_t SignBit = 1ULL << (MVT::getSizeInBits(VT)-1); - if (MaskedValueIsZero(N2, SignBit, TLI) && - MaskedValueIsZero(N1, SignBit, TLI)) - return getNode(ISD::UDIV, VT, N1, N2); - break; - } - - case ISD::AND: - case ISD::OR: - if (!CombinerEnabled) { - if (N1.Val->getOpcode() == ISD::SETCC && N2.Val->getOpcode() == ISD::SETCC){ - SDNode *LHS = N1.Val, *RHS = N2.Val; - SDOperand LL = LHS->getOperand(0), RL = RHS->getOperand(0); - SDOperand LR = LHS->getOperand(1), RR = RHS->getOperand(1); - ISD::CondCode Op1 = cast(LHS->getOperand(2))->get(); - ISD::CondCode Op2 = cast(RHS->getOperand(2))->get(); - - if (LR == RR && isa(LR) && - Op2 == Op1 && MVT::isInteger(LL.getValueType())) { - // (X != 0) | (Y != 0) -> (X|Y != 0) - // (X == 0) & (Y == 0) -> (X|Y == 0) - // (X < 0) | (Y < 0) -> (X|Y < 0) - if (cast(LR)->getValue() == 0 && - ((Op2 == ISD::SETEQ && Opcode == ISD::AND) || - (Op2 == ISD::SETNE && Opcode == ISD::OR) || - (Op2 == ISD::SETLT && Opcode == ISD::OR))) - return getSetCC(VT, getNode(ISD::OR, LR.getValueType(), LL, RL), LR, - Op2); - - if (cast(LR)->isAllOnesValue()) { - // (X == -1) & (Y == -1) -> (X&Y == -1) - // (X != -1) | (Y != -1) -> (X&Y != -1) - // (X > -1) | (Y > -1) -> (X&Y > -1) - if ((Opcode == ISD::AND && Op2 == ISD::SETEQ) || - (Opcode == ISD::OR && Op2 == ISD::SETNE) || - (Opcode == ISD::OR && Op2 == ISD::SETGT)) - return getSetCC(VT, getNode(ISD::AND, LR.getValueType(), LL, RL), - LR, Op2); - // (X > -1) & (Y > -1) -> (X|Y > -1) - if (Opcode == ISD::AND && Op2 == ISD::SETGT) - return getSetCC(VT, getNode(ISD::OR, LR.getValueType(), LL, RL), - LR, Op2); - } - } - - // (X op1 Y) | (Y op2 X) -> (X op1 Y) | (X swapop2 Y) - if (LL == RR && LR == RL) { - Op2 = ISD::getSetCCSwappedOperands(Op2); - goto MatchedBackwards; - } - - if (LL == RL && LR == RR) { - MatchedBackwards: - ISD::CondCode Result; - bool isInteger = MVT::isInteger(LL.getValueType()); - if (Opcode == ISD::OR) - Result = ISD::getSetCCOrOperation(Op1, Op2, isInteger); - else - Result = ISD::getSetCCAndOperation(Op1, Op2, isInteger); - - if (Result != ISD::SETCC_INVALID) - return getSetCC(LHS->getValueType(0), LL, LR, Result); - } - } - - // and/or zext(a), zext(b) -> zext(and/or a, b) - if (N1.getOpcode() == ISD::ZERO_EXTEND && - N2.getOpcode() == ISD::ZERO_EXTEND && - N1.getOperand(0).getValueType() == N2.getOperand(0).getValueType()) - return getNode(ISD::ZERO_EXTEND, VT, - getNode(Opcode, N1.getOperand(0).getValueType(), - N1.getOperand(0), N2.getOperand(0))); - } - break; - case ISD::XOR: - if (!CombinerEnabled) { - if (N1 == N2) return getConstant(0, VT); // xor X, Y -> 0 - } - break; - case ISD::ADD: - if (!CombinerEnabled) { - if (N1.getOpcode() == ISD::SUB && isa(N1.getOperand(0)) && - cast(N1.getOperand(0))->getValue() == 0) - return getNode(ISD::SUB, VT, N2, N1.getOperand(1)); // (0-A)+B -> B-A - if (N2.getOpcode() == ISD::SUB && isa(N2.getOperand(0)) && - cast(N2.getOperand(0))->getValue() == 0) - return getNode(ISD::SUB, VT, N1, N2.getOperand(1)); // A+(0-B) -> A-B - if (N2.getOpcode() == ISD::SUB && N1 == N2.Val->getOperand(1)) - return N2.Val->getOperand(0); // A+(B-A) -> B - } - break; - case ISD::FADD: - if (!CombinerEnabled) { - if (N2.getOpcode() == ISD::FNEG) // (A+ (-B) -> A-B - return getNode(ISD::FSUB, VT, N1, N2.getOperand(0)); - if (N1.getOpcode() == ISD::FNEG) // ((-A)+B) -> B-A - return getNode(ISD::FSUB, VT, N2, N1.getOperand(0)); - } - break; - - case ISD::SUB: - if (!CombinerEnabled) { - if (N1.getOpcode() == ISD::ADD) { - if (N1.Val->getOperand(0) == N2) - return N1.Val->getOperand(1); // (A+B)-A == B - if (N1.Val->getOperand(1) == N2) - return N1.Val->getOperand(0); // (A+B)-B == A - } - } - break; - case ISD::FSUB: - if (!CombinerEnabled) { - if (N2.getOpcode() == ISD::FNEG) // (A- (-B) -> A+B - return getNode(ISD::FADD, VT, N1, N2.getOperand(0)); - } - break; case ISD::FP_ROUND_INREG: if (cast(N2)->getVT() == VT) return N1; // Not actually rounding. break; case ISD::SIGN_EXTEND_INREG: { MVT::ValueType EVT = cast(N2)->getVT(); if (EVT == VT) return N1; // Not actually extending - if (!CombinerEnabled) { - // If we are sign extending an extension, use the original source. - if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG || - N1.getOpcode() == ISD::AssertSext) - if (cast(N1.getOperand(1))->getVT() <= EVT) - return N1; - - // If we are sign extending a sextload, return just the load. - if (N1.getOpcode() == ISD::SEXTLOAD) - if (cast(N1.getOperand(3))->getVT() <= EVT) - return N1; - - // If we are extending the result of a setcc, and we already know the - // contents of the top bits, eliminate the extension. - if (N1.getOpcode() == ISD::SETCC && - TLI.getSetCCResultContents() == - TargetLowering::ZeroOrNegativeOneSetCCResult) - return N1; - - // If we are sign extending the result of an (and X, C) operation, and we - // know the extended bits are zeros already, don't do the extend. - if (N1.getOpcode() == ISD::AND) - if (ConstantSDNode *N1C = dyn_cast(N1.getOperand(1))) { - uint64_t Mask = N1C->getValue(); - unsigned NumBits = MVT::getSizeInBits(EVT); - if ((Mask & (~0ULL << (NumBits-1))) == 0) - return N1; - } - } break; } @@ -1840,36 +1360,6 @@ return N3; // select false, X, Y -> Y if (N2 == N3) return N2; // select C, X, X -> X - - if (!CombinerEnabled) { - if (VT == MVT::i1) { // Boolean SELECT - if (N2C) { - if (N2C->getValue()) // select C, 1, X -> C | X - return getNode(ISD::OR, VT, N1, N3); - else // select C, 0, X -> ~C & X - return getNode(ISD::AND, VT, - getNode(ISD::XOR, N1.getValueType(), N1, - getConstant(1, N1.getValueType())), N3); - } else if (N3C) { - if (N3C->getValue()) // select C, X, 1 -> ~C | X - return getNode(ISD::OR, VT, - getNode(ISD::XOR, N1.getValueType(), N1, - getConstant(1, N1.getValueType())), N2); - else // select C, X, 0 -> C & X - return getNode(ISD::AND, VT, N1, N2); - } - - if (N1 == N2) // X ? X : Y --> X ? 1 : Y --> X | Y - return getNode(ISD::OR, VT, N1, N3); - if (N1 == N3) // X ? Y : X --> X ? Y : 0 --> X & Y - return getNode(ISD::AND, VT, N1, N2); - } - if (N1.getOpcode() == ISD::SETCC) { - SDOperand Simp = SimplifySelectCC(N1.getOperand(0), N1.getOperand(1), N2, - N3, cast(N1.getOperand(2))->get()); - if (Simp.Val) return Simp; - } - } break; case ISD::BRCOND: if (N2C) @@ -1999,24 +1489,6 @@ assert(Ops.size() == 5 && "BR_CC takes 5 operands!"); assert(Ops[2].getValueType() == Ops[3].getValueType() && "LHS/RHS of comparison should match types!"); - - if (CombinerEnabled) break; // xforms moved to dag combine. - - // Use SimplifySetCC to simplify SETCC's. - SDOperand Simp = SimplifySetCC(MVT::i1, Ops[2], Ops[3], - cast(Ops[1])->get()); - if (Simp.Val) { - if (ConstantSDNode *C = dyn_cast(Simp)) { - if (C->getValue() & 1) // Unconditional branch - return getNode(ISD::BR, MVT::Other, Ops[0], Ops[4]); - else - return Ops[0]; // Unconditional Fall through - } else if (Simp.Val->getOpcode() == ISD::SETCC) { - Ops[2] = Simp.getOperand(0); - Ops[3] = Simp.getOperand(1); - Ops[1] = Simp.getOperand(2); - } - } break; } } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.87 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.88 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.87 Wed Oct 5 01:09:10 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Oct 10 11:47:10 2005 @@ -37,18 +37,6 @@ #include using namespace llvm; -// Temporary command line code to enable use of the dag combiner as a beta -// option. -namespace llvm { - bool CombinerEnabled; -} -namespace { - cl::opt - CombineDAG("enable-dag-combiner", cl::Hidden, - cl::desc("Run the DAG combiner before and after Legalize"), - cl::location(CombinerEnabled), - cl::init(false)); -} #ifndef NDEBUG static cl::opt ViewDAGs("view-isel-dags", cl::Hidden, @@ -1289,8 +1277,8 @@ // types that are not supported by the target. BuildSelectionDAG(DAG, LLVMBB, PHINodesToUpdate, FuncInfo); - // Run the DAG combiner in pre-legalize mode, if we are told to do so - if (CombinerEnabled) DAG.Combine(false); + // Run the DAG combiner in pre-legalize mode. + DAG.Combine(false); DEBUG(std::cerr << "Lowered selection DAG:\n"); DEBUG(DAG.dump()); @@ -1302,8 +1290,8 @@ DEBUG(std::cerr << "Legalized selection DAG:\n"); DEBUG(DAG.dump()); - // Run the DAG combiner in post-legalize mode, if we are told to do so - if (CombinerEnabled) DAG.Combine(true); + // Run the DAG combiner in post-legalize mode. + DAG.Combine(true); if (ViewDAGs) DAG.viewGraph(); From lattner at cs.uiuc.edu Mon Oct 10 11:48:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 10 Oct 2005 11:48:11 -0500 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200510101648.LAA14321@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.172 -> 1.173 --- Log message: The dag combiner is on by default for llc now. Make scheduling llc-beta on ppc again. --- Diffs of the changes: (+1 -2) Makefile.programs | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.172 llvm-test/Makefile.programs:1.173 --- llvm-test/Makefile.programs:1.172 Sun Oct 9 02:11:33 2005 +++ llvm-test/Makefile.programs Mon Oct 10 11:47:59 2005 @@ -187,8 +187,7 @@ endif#DISABLE_DIFFS ifeq ($(ARCH),PowerPC) -LLCBETAOPTION := -enable-dag-combiner -#-sched=simple +LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),Alpha) LLCBETAOPTION := -enable-alpha-FTOI -enable-lsr-for-alpha From lattner at cs.uiuc.edu Mon Oct 10 11:49:33 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 10 Oct 2005 11:49:33 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200510101649.LAA14390@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.204 -> 1.205 --- Log message: This function is now dead --- Diffs of the changes: (+0 -110) SelectionDAG.cpp | 110 ------------------------------------------------------- 1 files changed, 110 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.204 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.205 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.204 Mon Oct 10 11:47:10 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Oct 10 11:49:22 2005 @@ -576,116 +576,6 @@ return SDOperand(Reg, 0); } -/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use -/// this predicate to simplify operations downstream. V and Mask are known to -/// be the same type. -static bool MaskedValueIsZero(const SDOperand &Op, uint64_t Mask, - const TargetLowering &TLI) { - unsigned SrcBits; - if (Mask == 0) return true; - - // If we know the result of a setcc has the top bits zero, use this info. - switch (Op.getOpcode()) { - case ISD::Constant: - return (cast(Op)->getValue() & Mask) == 0; - - case ISD::SETCC: - return ((Mask & 1) == 0) && - TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult; - - case ISD::ZEXTLOAD: - SrcBits = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); - return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. - case ISD::ZERO_EXTEND: - SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType()); - return MaskedValueIsZero(Op.getOperand(0),Mask & ((1ULL << SrcBits)-1),TLI); - case ISD::AssertZext: - SrcBits = MVT::getSizeInBits(cast(Op.getOperand(1))->getVT()); - return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. - case ISD::AND: - // If either of the operands has zero bits, the result will too. - if (MaskedValueIsZero(Op.getOperand(1), Mask, TLI) || - MaskedValueIsZero(Op.getOperand(0), Mask, TLI)) - return true; - - // (X & C1) & C2 == 0 iff C1 & C2 == 0. - if (ConstantSDNode *AndRHS = dyn_cast(Op.getOperand(1))) - return MaskedValueIsZero(Op.getOperand(0),AndRHS->getValue() & Mask, TLI); - return false; - case ISD::OR: - case ISD::XOR: - return MaskedValueIsZero(Op.getOperand(0), Mask, TLI) && - MaskedValueIsZero(Op.getOperand(1), Mask, TLI); - case ISD::SELECT: - return MaskedValueIsZero(Op.getOperand(1), Mask, TLI) && - MaskedValueIsZero(Op.getOperand(2), Mask, TLI); - case ISD::SELECT_CC: - return MaskedValueIsZero(Op.getOperand(2), Mask, TLI) && - MaskedValueIsZero(Op.getOperand(3), Mask, TLI); - case ISD::SRL: - // (ushr X, C1) & C2 == 0 iff X & (C2 << C1) == 0 - if (ConstantSDNode *ShAmt = dyn_cast(Op.getOperand(1))) { - uint64_t NewVal = Mask << ShAmt->getValue(); - SrcBits = MVT::getSizeInBits(Op.getValueType()); - if (SrcBits != 64) NewVal &= (1ULL << SrcBits)-1; - return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI); - } - return false; - case ISD::SHL: - // (ushl X, C1) & C2 == 0 iff X & (C2 >> C1) == 0 - if (ConstantSDNode *ShAmt = dyn_cast(Op.getOperand(1))) { - uint64_t NewVal = Mask >> ShAmt->getValue(); - return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI); - } - return false; - case ISD::ADD: - // (add X, Y) & C == 0 iff (X&C)|(Y&C) == 0 and all bits are low bits. - if ((Mask&(Mask+1)) == 0) { // All low bits - if (MaskedValueIsZero(Op.getOperand(0), Mask, TLI) && - MaskedValueIsZero(Op.getOperand(1), Mask, TLI)) { - std::cerr << "MASK: "; - Op.getOperand(0).Val->dump(); - std::cerr << " - "; - Op.getOperand(1).Val->dump(); - std::cerr << "\n"; - return true; - } - } - break; - case ISD::SUB: - if (ConstantSDNode *CLHS = dyn_cast(Op.getOperand(0))) { - // We know that the top bits of C-X are clear if X contains less bits - // than C (i.e. no wrap-around can happen). For example, 20-X is - // positive if we can prove that X is >= 0 and < 16. - unsigned Bits = MVT::getSizeInBits(CLHS->getValueType(0)); - if ((CLHS->getValue() & (1 << (Bits-1))) == 0) { // sign bit clear - unsigned NLZ = CountLeadingZeros_64(CLHS->getValue()+1); - uint64_t MaskV = (1ULL << (63-NLZ))-1; - if (MaskedValueIsZero(Op.getOperand(1), ~MaskV, TLI)) { - // High bits are clear this value is known to be >= C. - unsigned NLZ2 = CountLeadingZeros_64(CLHS->getValue()); - if ((Mask & ((1ULL << (64-NLZ2))-1)) == 0) - return true; - } - } - } - break; - case ISD::CTTZ: - case ISD::CTLZ: - case ISD::CTPOP: - // Bit counting instructions can not set the high bits of the result - // register. The max number of bits sets depends on the input. - return (Mask & (MVT::getSizeInBits(Op.getValueType())*2-1)) == 0; - - // TODO we could handle some SRA cases here. - default: break; - } - - return false; -} - - - SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1, SDOperand N2, ISD::CondCode Cond) { // These setcc operations always fold. From lattner at cs.uiuc.edu Mon Oct 10 11:51:51 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 10 Oct 2005 11:51:51 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510101651.LAA14530@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.24 -> 1.25 --- Log message: Add ISD::ADD to MaskedValueIsZero --- Diffs of the changes: (+8 -0) DAGCombiner.cpp | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.24 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.25 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.24 Sun Oct 9 17:59:08 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Oct 10 11:51:40 2005 @@ -215,6 +215,14 @@ return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI); } return false; + case ISD::ADD: + // (add X, Y) & C == 0 iff (X&C)&(Y&C) == 0 and all bits are low bits. + if ((Mask&(Mask+1)) == 0) { // All low bits + if (MaskedValueIsZero(Op.getOperand(0), Mask, TLI) && + MaskedValueIsZero(Op.getOperand(1), Mask, TLI)) + return true; + } + break; case ISD::SUB: if (ConstantSDNode *CLHS = dyn_cast(Op.getOperand(0))) { // We know that the top bits of C-X are clear if X contains less bits From lattner at cs.uiuc.edu Mon Oct 10 11:52:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 10 Oct 2005 11:52:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510101652.LAA14587@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.25 -> 1.26 --- Log message: Fix comment --- Diffs of the changes: (+1 -1) DAGCombiner.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.25 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.26 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.25 Mon Oct 10 11:51:40 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Oct 10 11:52:03 2005 @@ -216,7 +216,7 @@ } return false; case ISD::ADD: - // (add X, Y) & C == 0 iff (X&C)&(Y&C) == 0 and all bits are low bits. + // (add X, Y) & C == 0 iff (X&C)|(Y&C) == 0 and all bits are low bits. if ((Mask&(Mask+1)) == 0) { // All low bits if (MaskedValueIsZero(Op.getOperand(0), Mask, TLI) && MaskedValueIsZero(Op.getOperand(1), Mask, TLI)) From lattner at cs.uiuc.edu Mon Oct 10 16:21:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 10 Oct 2005 16:21:48 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/and-elim.ll Message-ID: <200510102121.QAA02466@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: and-elim.ll added (r1.1) --- Log message: A testcase sitting in my tree --- Diffs of the changes: (+11 -0) and-elim.ll | 11 +++++++++++ 1 files changed, 11 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/and-elim.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/and-elim.ll:1.1 *** /dev/null Mon Oct 10 16:21:46 2005 --- llvm/test/Regression/CodeGen/PowerPC/and-elim.ll Mon Oct 10 16:21:36 2005 *************** *** 0 **** --- 1,11 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 && + ; RUN: llvm-as < %s | llc -march=ppc32 | not grep rlwin + + void %test(ubyte* %P) { + %W = load ubyte* %P + %X = shl ubyte %W, ubyte 1 + %Y = add ubyte %X, 2 + %Z = and ubyte %Y, 254 ; dead and + store ubyte %Z, ubyte* %P + ret void + } From natebegeman at mac.com Mon Oct 10 16:27:00 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 10 Oct 2005 16:27:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510102127.QAA04294@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.26 -> 1.27 --- Log message: Teach the DAGCombiner several new tricks, teaching it how to turn sext_inreg into zext_inreg based on the signbit (fires a lot), srem into urem, etc. --- Diffs of the changes: (+46 -32) DAGCombiner.cpp | 78 +++++++++++++++++++++++++++++++++----------------------- 1 files changed, 46 insertions(+), 32 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.26 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.27 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.26 Mon Oct 10 11:52:03 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Oct 10 16:26:48 2005 @@ -20,7 +20,6 @@ // ZERO_EXTEND/SIGN_EXTEND by converting them to an ANY_EXTEND node which // we don't have yet. // -// FIXME: select C, 16, 0 -> shr C, 4 // FIXME: select C, pow2, pow2 -> something smart // FIXME: trunc(select X, Y, Z) -> select X, trunc(Y), trunc(Z) // FIXME: (select C, load A, load B) -> load (select C, A, B) @@ -30,20 +29,13 @@ // FIXME: TRUNC (LOAD) -> EXT_LOAD/LOAD(smaller) // FIXME: mul (x, const) -> shifts + adds // FIXME: undef values -// FIXME: zero extend when top bits are 0 -> drop it ? // FIXME: make truncate see through SIGN_EXTEND and AND -// FIXME: sext_in_reg(setcc) on targets that return zero or one, and where -// EVT != MVT::i1 can drop the sext. // FIXME: (sra (sra x, c1), c2) -> (sra x, c1+c2) // FIXME: verify that getNode can't return extends with an operand whose type // is >= to that of the extend. // FIXME: divide by zero is currently left unfolded. do we want to turn this // into an undef? // FIXME: select ne (select cc, 1, 0), 0, true, false -> select cc, true, false -// FIXME: sext_inreg(SRL) -> SRA: -// int %simple(uint %X) { %tmp.4 = shr uint %X, ubyte 16 -// %tmp.5 = cast uint %tmp.4 to short %tmp.6 = cast short %tmp.5 to int -// ret int %tmp.6 } // //===----------------------------------------------------------------------===// @@ -154,8 +146,8 @@ }; } -/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use -/// this predicate to simplify operations downstream. V and Mask are known to +/// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero. We use +/// this predicate to simplify operations downstream. Op and Mask are known to /// be the same type. static bool MaskedValueIsZero(const SDOperand &Op, uint64_t Mask, const TargetLowering &TLI) { @@ -167,7 +159,6 @@ case ISD::Constant: return (cast(Op)->getValue() & Mask) == 0; case ISD::SETCC: - // FIXME: teach this about non ZeroOrOne values, such as 0 or -1 return ((Mask & 1) == 0) && TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult; case ISD::ZEXTLOAD: @@ -184,7 +175,6 @@ if (MaskedValueIsZero(Op.getOperand(1), Mask, TLI) || MaskedValueIsZero(Op.getOperand(0), Mask, TLI)) return true; - // (X & C1) & C2 == 0 iff C1 & C2 == 0. if (ConstantSDNode *AndRHS = dyn_cast(Op.getOperand(1))) return MaskedValueIsZero(Op.getOperand(0),AndRHS->getValue() & Mask, TLI); @@ -545,15 +535,12 @@ if (N0C && N1C && !N1C->isNullValue()) return DAG.getConstant(N0C->getSignExtended() / N1C->getSignExtended(), N->getValueType(0)); - // If we know the sign bits of both operands are zero, strength reduce to a // udiv instead. Handles (X&15) /s 4 -> X&15 >> 2 uint64_t SignBit = 1ULL << (MVT::getSizeInBits(VT)-1); if (MaskedValueIsZero(N1, SignBit, TLI) && MaskedValueIsZero(N0, SignBit, TLI)) return DAG.getNode(ISD::UDIV, N1.getValueType(), N0, N1); - - return SDOperand(); } @@ -578,6 +565,7 @@ SDOperand DAGCombiner::visitSREM(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); + MVT::ValueType VT = N->getValueType(0); ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); @@ -585,6 +573,12 @@ if (N0C && N1C && !N1C->isNullValue()) return DAG.getConstant(N0C->getSignExtended() % N1C->getSignExtended(), N->getValueType(0)); + // If we know the sign bits of both operands are zero, strength reduce to a + // urem instead. Handles (X & 0x0FFFFFFF) %s 16 -> X&15 + uint64_t SignBit = 1ULL << (MVT::getSizeInBits(VT)-1); + if (MaskedValueIsZero(N1, SignBit, TLI) && + MaskedValueIsZero(N0, SignBit, TLI)) + return DAG.getNode(ISD::UREM, N1.getValueType(), N0, N1); return SDOperand(); } @@ -598,7 +592,10 @@ if (N0C && N1C && !N1C->isNullValue()) return DAG.getConstant(N0C->getValue() % N1C->getValue(), N->getValueType(0)); - // FIXME: c2 power of 2 -> mask? + // fold (urem x, pow2) -> (and x, pow2-1) + if (N1C && !N1C->isNullValue() && isPowerOf2_64(N1C->getValue())) + return DAG.getNode(ISD::AND, N0.getValueType(), N0, + DAG.getConstant(N1C->getValue()-1, N1.getValueType())); return SDOperand(); } @@ -1173,6 +1170,7 @@ ConstantSDNode *N0C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); MVT::ValueType EVT = cast(N1)->getVT(); + unsigned EVTBits = MVT::getSizeInBits(EVT); // fold (sext_in_reg c1) -> c1 if (N0C) { @@ -1200,23 +1198,20 @@ return N0; } // fold (sext_in_reg (setcc x)) -> setcc x iff (setcc x) == 0 or -1 - // FIXME: teach isSetCCEquivalent about 0, -1 and then use it here if (N0.getOpcode() == ISD::SETCC && TLI.getSetCCResultContents() == TargetLowering::ZeroOrNegativeOneSetCCResult) return N0; - // FIXME: this code is currently just ported over from SelectionDAG.cpp - // we probably actually want to handle this in two pieces. Rather than - // checking all the top bits for zero, just check the sign bit here and turn - // it into a zero extend inreg (AND with constant). - // then, let the code for AND figure out if the mask is superfluous rather - // than doing so here. - if (N0.getOpcode() == ISD::AND && - N0.getOperand(1).getOpcode() == ISD::Constant) { - uint64_t Mask = cast(N0.getOperand(1))->getValue(); - unsigned NumBits = MVT::getSizeInBits(EVT); - if ((Mask & (~0ULL << (NumBits-1))) == 0) - return N0; + // fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is zero + if (MaskedValueIsZero(N0, 1ULL << (EVTBits-1), TLI)) + return DAG.getNode(ISD::AND, N0.getValueType(), N0, + DAG.getConstant(~0ULL >> (64-EVTBits), VT)); + // fold (sext_in_reg (srl x)) -> sra x + if (N0.getOpcode() == ISD::SRL && + N0.getOperand(1).getOpcode() == ISD::Constant && + cast(N0.getOperand(1))->getValue() == EVTBits) { + return DAG.getNode(ISD::SRA, N0.getValueType(), N0.getOperand(0), + N0.getOperand(1)); } return SDOperand(); } @@ -1590,8 +1585,7 @@ MVT::ValueType AType = N2.getValueType(); if (XType >= AType) { // and (sra X, size(X)-1, A) -> "and (srl X, C2), A" iff A is a - // single-bit constant. FIXME: remove once the dag combiner - // exists. + // single-bit constant. if (N2C && ((N2C->getValue() & (N2C->getValue()-1)) == 0)) { unsigned ShCtV = Log2_64(N2C->getValue()); ShCtV = MVT::getSizeInBits(XType)-ShCtV-1; @@ -1615,7 +1609,27 @@ return DAG.getNode(ISD::AND, AType, Shift, N2); } } - + + // fold select C, 16, 0 -> shl C, 4 + if (N2C && N3C && N3C->isNullValue() && isPowerOf2_64(N2C->getValue()) && + TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult) { + // Get a SetCC of the condition + // FIXME: Should probably make sure that setcc is legal if we ever have a + // target where it isn't. + SDOperand Temp, SCC = DAG.getSetCC(TLI.getSetCCResultTy(), N0, N1, CC); + WorkList.push_back(SCC.Val); + // cast from setcc result type to select result type + if (AfterLegalize) + Temp = DAG.getZeroExtendInReg(SCC, N2.getValueType()); + else + Temp = DAG.getNode(ISD::ZERO_EXTEND, N2.getValueType(), SCC); + WorkList.push_back(Temp.Val); + // shl setcc result by log2 n2c + return DAG.getNode(ISD::SHL, N2.getValueType(), Temp, + DAG.getConstant(Log2_64(N2C->getValue()), + TLI.getShiftAmountTy())); + } + // Check to see if this is the equivalent of setcc // FIXME: Turn all of these into setcc if setcc if setcc is legal // otherwise, go ahead with the folds. From lattner at cs.uiuc.edu Mon Oct 10 16:57:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 10 Oct 2005 16:57:49 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/store-load-fwd.ll Message-ID: <200510102157.QAA04865@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: store-load-fwd.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+7 -0) store-load-fwd.ll | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/store-load-fwd.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/store-load-fwd.ll:1.1 *** /dev/null Mon Oct 10 16:57:47 2005 --- llvm/test/Regression/CodeGen/PowerPC/store-load-fwd.ll Mon Oct 10 16:57:37 2005 *************** *** 0 **** --- 1,7 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 && + ; RUN: llvm-as < %s | llc -march=ppc32 | not grep lwz + int %test(int* %P) { + store int 1, int* %P + %V = load int* %P + ret int %V + } From lattner at cs.uiuc.edu Mon Oct 10 17:04:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 10 Oct 2005 17:04:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510102204.RAA04974@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.27 -> 1.28 --- Log message: Add support for CombineTo, allowing the dag combiner to replace nodes with multiple results. Use this support to implement trivial store->load forwarding, implementing CodeGen/PowerPC/store-load-fwd.ll. Though this is the most simple case and can be extended in the future, it is still useful. For example, it speeds up 197.parser by 6.2% by avoiding an LSU reject in xalloc: stw r6, lo16(l5_end_of_array)(r2) addi r2, r5, -4 stwx r5, r4, r2 - lwzx r5, r4, r2 - rlwinm r5, r5, 0, 0, 30 stwx r5, r4, r2 lwz r2, -4(r4) ori r2, r2, 1 --- Diffs of the changes: (+56 -2) DAGCombiner.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 56 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.27 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.28 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.27 Mon Oct 10 16:26:48 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Oct 10 17:04:48 2005 @@ -23,7 +23,6 @@ // FIXME: select C, pow2, pow2 -> something smart // FIXME: trunc(select X, Y, Z) -> select X, trunc(Y), trunc(Z) // FIXME: (select C, load A, load B) -> load (select C, A, B) -// FIXME: store -> load -> forward substitute // FIXME: Dead stores -> nuke // FIXME: shr X, (and Y,31) -> shr X, Y // FIXME: TRUNC (LOAD) -> EXT_LOAD/LOAD(smaller) @@ -36,6 +35,7 @@ // FIXME: divide by zero is currently left unfolded. do we want to turn this // into an undef? // FIXME: select ne (select cc, 1, 0), 0, true, false -> select cc, true, false +// FIXME: reassociate (X+C)+Y into (X+Y)+C if the inner expression has one use // //===----------------------------------------------------------------------===// @@ -76,6 +76,37 @@ WorkList.end()); } + SDOperand CombineTo(SDNode *N, const std::vector &To) { + DEBUG(std::cerr << "\nReplacing "; N->dump(); + std::cerr << "\nWith: "; To[0].Val->dump(); + std::cerr << " and " << To.size()-1 << " other values\n"); + std::vector NowDead; + DAG.ReplaceAllUsesWith(N, To, &NowDead); + + // Push the new nodes and any users onto the worklist + for (unsigned i = 0, e = To.size(); i != e; ++i) { + WorkList.push_back(To[i].Val); + AddUsersToWorkList(To[i].Val); + } + + // Nodes can end up on the worklist more than once. Make sure we do + // not process a node that has been replaced. + removeFromWorkList(N); + for (unsigned i = 0, e = NowDead.size(); i != e; ++i) + removeFromWorkList(NowDead[i]); + + // Finally, since the node is now dead, remove it from the graph. + DAG.DeleteNode(N); + return SDOperand(N, 0); + } + + SDOperand CombineTo(SDNode *N, SDOperand Res0, SDOperand Res1) { + std::vector To; + To.push_back(Res0); + To.push_back(Res1); + return CombineTo(N, To); + } + /// visit - call the node-specific routine that knows how to fold each /// particular type of node. SDOperand visit(SDNode *N); @@ -84,6 +115,7 @@ // node types. The semantics are as follows: // Return Value: // SDOperand.Val == 0 - No change was made + // SDOperand.Val == N - N was replaced, is dead, and is already handled. // otherwise - N should be replaced by the returned Operand. // SDOperand visitTokenFactor(SDNode *N); @@ -132,6 +164,8 @@ SDOperand visitBR_CC(SDNode *N); SDOperand visitBRTWOWAY_CC(SDNode *N); + SDOperand visitLOAD(SDNode *N); + SDOperand SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2); SDOperand SimplifySelectCC(SDOperand N0, SDOperand N1, SDOperand N2, SDOperand N3, ISD::CondCode CC); @@ -334,7 +368,8 @@ DEBUG(std::cerr << "\nReplacing "; N->dump(); std::cerr << "\nWith: "; RV.Val->dump(); std::cerr << '\n'); - DAG.ReplaceAllUsesWith(N, std::vector(1, RV)); + std::vector NowDead; + DAG.ReplaceAllUsesWith(N, std::vector(1, RV), &NowDead); // Push the new node and any users onto the worklist WorkList.push_back(RV.Val); @@ -343,6 +378,8 @@ // Nodes can end up on the worklist more than once. Make sure we do // not process a node that has been replaced. removeFromWorkList(N); + for (unsigned i = 0, e = NowDead.size(); i != e; ++i) + removeFromWorkList(NowDead[i]); // Finally, since the node is now dead, remove it from the graph. DAG.DeleteNode(N); @@ -401,6 +438,7 @@ case ISD::BRCONDTWOWAY: return visitBRCONDTWOWAY(N); case ISD::BR_CC: return visitBR_CC(N); case ISD::BRTWOWAY_CC: return visitBRTWOWAY_CC(N); + case ISD::LOAD: return visitLOAD(N); } return SDOperand(); } @@ -1513,6 +1551,22 @@ return SDOperand(); } +SDOperand DAGCombiner::visitLOAD(SDNode *N) { + SDOperand Chain = N->getOperand(0); + SDOperand Ptr = N->getOperand(1); + SDOperand SrcValue = N->getOperand(2); + + // If this load is directly stored, replace the load value with the stored + // value. + // TODO: Handle store large -> read small portion. + // TODO: Handle TRUNCSTORE/EXTLOAD + if (Chain.getOpcode() == ISD::STORE && Chain.getOperand(2) == Ptr && + Chain.getOperand(1).getValueType() == N->getValueType(0)) + return CombineTo(N, Chain.getOperand(1), Chain); + + return SDOperand(); +} + SDOperand DAGCombiner::SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2){ assert(N0.getOpcode() ==ISD::SETCC && "First argument must be a SetCC node!"); From lattner at cs.uiuc.edu Mon Oct 10 17:31:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 10 Oct 2005 17:31:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510102231.RAA05075@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.28 -> 1.29 --- Log message: Implement trivial DSE. If two stores are neighbors and store to the same location, replace them with a new store of the last value. This occurs in the same neighborhood in 197.parser, speeding it up about 1.5% --- Diffs of the changes: (+29 -0) DAGCombiner.cpp | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.28 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.29 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.28 Mon Oct 10 17:04:48 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Oct 10 17:31:19 2005 @@ -77,6 +77,7 @@ } SDOperand CombineTo(SDNode *N, const std::vector &To) { + ++NodesCombined; DEBUG(std::cerr << "\nReplacing "; N->dump(); std::cerr << "\nWith: "; To[0].Val->dump(); std::cerr << " and " << To.size()-1 << " other values\n"); @@ -99,6 +100,12 @@ DAG.DeleteNode(N); return SDOperand(N, 0); } + + SDOperand CombineTo(SDNode *N, SDOperand Res) { + std::vector To; + To.push_back(Res); + return CombineTo(N, To); + } SDOperand CombineTo(SDNode *N, SDOperand Res0, SDOperand Res1) { std::vector To; @@ -165,6 +172,7 @@ SDOperand visitBRTWOWAY_CC(SDNode *N); SDOperand visitLOAD(SDNode *N); + SDOperand visitSTORE(SDNode *N); SDOperand SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2); SDOperand SimplifySelectCC(SDOperand N0, SDOperand N1, SDOperand N2, @@ -439,6 +447,7 @@ case ISD::BR_CC: return visitBR_CC(N); case ISD::BRTWOWAY_CC: return visitBRTWOWAY_CC(N); case ISD::LOAD: return visitLOAD(N); + case ISD::STORE: return visitSTORE(N); } return SDOperand(); } @@ -1567,6 +1576,26 @@ return SDOperand(); } +SDOperand DAGCombiner::visitSTORE(SDNode *N) { + SDOperand Chain = N->getOperand(0); + SDOperand Value = N->getOperand(1); + SDOperand Ptr = N->getOperand(2); + SDOperand SrcValue = N->getOperand(3); + + // If this is a store that kills a previous store, remove the previous store. + if (Chain.getOpcode() == ISD::STORE && Chain.getOperand(2) == Ptr) { + // Create a new store of Value that replaces both stores. + SDNode *PrevStore = Chain.Val; + SDOperand NewStore = DAG.getNode(ISD::STORE, MVT::Other, + PrevStore->getOperand(0), Value, Ptr, + SrcValue); + CombineTo(PrevStore, NewStore); // Nuke the previous store. + return NewStore; // Replace this store with NewStore. + } + + return SDOperand(); +} + SDOperand DAGCombiner::SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2){ assert(N0.getOpcode() ==ISD::SETCC && "First argument must be a SetCC node!"); From lattner at cs.uiuc.edu Mon Oct 10 18:00:20 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 10 Oct 2005 18:00:20 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510102300.SAA09206@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.29 -> 1.30 --- Log message: clean up some corner cases --- Diffs of the changes: (+6 -2) DAGCombiner.cpp | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.29 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.30 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.29 Mon Oct 10 17:31:19 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Oct 10 18:00:08 2005 @@ -1583,14 +1583,18 @@ SDOperand SrcValue = N->getOperand(3); // If this is a store that kills a previous store, remove the previous store. - if (Chain.getOpcode() == ISD::STORE && Chain.getOperand(2) == Ptr) { + if (Chain.getOpcode() == ISD::STORE && Chain.getOperand(2) == Ptr && + Chain.Val->hasOneUse() /* Avoid introducing DAG cycles */) { // Create a new store of Value that replaces both stores. SDNode *PrevStore = Chain.Val; + if (PrevStore->getOperand(1) == Value) // Same value multiply stored. + return Chain; SDOperand NewStore = DAG.getNode(ISD::STORE, MVT::Other, PrevStore->getOperand(0), Value, Ptr, SrcValue); + CombineTo(N, NewStore); // Nuke this store. CombineTo(PrevStore, NewStore); // Nuke the previous store. - return NewStore; // Replace this store with NewStore. + return SDOperand(N, 0); } return SDOperand(); From lattner at cs.uiuc.edu Tue Oct 11 01:07:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 11 Oct 2005 01:07:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510110607.BAA14596@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.30 -> 1.31 --- Log message: Add a canonicalization that got lost, fixing PowerPC/fold-li.ll:SUB --- Diffs of the changes: (+5 -3) DAGCombiner.cpp | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.30 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.31 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.30 Mon Oct 10 18:00:08 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Oct 11 01:07:15 2005 @@ -517,9 +517,11 @@ if (N0C && N1C) return DAG.getConstant(N0C->getValue() - N1C->getValue(), N->getValueType(0)); - // fold (sub x, 0) -> x - if (N1C && N1C->isNullValue()) - return N0; + // fold (sub x, c) -> (add x, -c) + if (N1C) + return DAG.getNode(ISD::ADD, N0.getValueType(), N0, + DAG.getConstant(-N1C->getValue(), N0.getValueType())); + // fold (A+B)-A -> B if (N0.getOpcode() == ISD::ADD && N0.getOperand(0) == N1) return N0.getOperand(1); From lattner at cs.uiuc.edu Tue Oct 11 12:56:46 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 11 Oct 2005 12:56:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510111756.MAA23922@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.31 -> 1.32 --- Log message: Fix a powerpc crash on CodeGen/Generic/llvm-ct-intrinsics.ll --- Diffs of the changes: (+1 -1) DAGCombiner.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.31 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.32 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.31 Tue Oct 11 01:07:15 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Oct 11 12:56:34 2005 @@ -724,7 +724,7 @@ return DAG.getNode(ISD::AND, VT, N0.getOperand(0), N1); } // fold (and (or x, 0xFFFF), 0xFF) -> 0xFF - if (N0.getOpcode() == ISD::OR) + if (N0.getOpcode() == ISD::OR && N1C) if (ConstantSDNode *ORI = dyn_cast(N0.getOperand(1))) if ((ORI->getValue() & N1C->getValue()) == N1C->getValue()) return N1; From lattner at cs.uiuc.edu Tue Oct 11 13:18:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 11 Oct 2005 13:18:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200510111818.NAA24155@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.65 -> 1.66 --- Log message: Fix another lsr-is-nondeterministic case --- Diffs of the changes: (+10 -6) LoopStrengthReduce.cpp | 16 ++++++++++------ 1 files changed, 10 insertions(+), 6 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.65 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.66 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.65 Sun Oct 9 01:24:02 2005 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue Oct 11 13:17:57 2005 @@ -970,19 +970,23 @@ IVStrideUse *CondUse = 0; const SCEVHandle *CondStride = 0; - for (std::map::iterator - I = IVUsesByStride.begin(), E = IVUsesByStride.end(); - I != E && !CondUse; ++I) - for (std::vector::iterator UI = I->second.Users.begin(), - E = I->second.Users.end(); UI != E; ++UI) + for (unsigned Stride = 0, e = StrideOrder.size(); Stride != e && !CondUse; + ++Stride) { + std::map::iterator SI = + IVUsesByStride.find(StrideOrder[Stride]); + assert(SI != IVUsesByStride.end() && "Stride doesn't exist!"); + + for (std::vector::iterator UI = SI->second.Users.begin(), + E = SI->second.Users.end(); UI != E; ++UI) if (UI->User == Cond) { CondUse = &*UI; - CondStride = &I->first; + CondStride = &SI->first; // NOTE: we could handle setcc instructions with multiple uses here, but // InstCombine does it as well for simple uses, it's not clear that it // occurs enough in real life to handle. break; } + } if (!CondUse) return; // setcc doesn't use the IV. // setcc stride is complex, don't mess with users. From lattner at cs.uiuc.edu Tue Oct 11 13:28:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 11 Oct 2005 13:28:59 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll Message-ID: <200510111828.NAA24211@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LoopStrengthReduce: dont_reduce_bytes.ll updated: 1.2 -> 1.3 --- Log message: lsr doesn't emit gep instructions anymore --- Diffs of the changes: (+1 -1) dont_reduce_bytes.ll | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll diff -u llvm/test/Regression/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll:1.2 llvm/test/Regression/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll:1.3 --- llvm/test/Regression/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll:1.2 Mon Aug 1 12:10:50 2005 +++ llvm/test/Regression/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll Tue Oct 11 13:28:48 2005 @@ -1,7 +1,7 @@ ; Don't reduce the byte access to P[i], at least not on targets that ; support an efficient 'mem[r1+r2]' addressing mode. -; RUN: llvm-as < %s | opt -loop-reduce | llvm-dis | grep 'getelementptr.*PTR.*INDVAR' +; RUN: llvm-as < %s | opt -loop-reduce -disable-output ; XFAIL: * From lattner at cs.uiuc.edu Tue Oct 11 13:31:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 11 Oct 2005 13:31:08 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200510111831.NAA24305@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.66 -> 1.67 --- Log message: Fix another problem where LSR was being nondeterminstic. Also remove elements from the end of a vector instead of the beginning --- Diffs of the changes: (+16 -10) LoopStrengthReduce.cpp | 26 ++++++++++++++++---------- 1 files changed, 16 insertions(+), 10 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.66 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.67 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.66 Tue Oct 11 13:17:57 2005 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue Oct 11 13:30:57 2005 @@ -474,10 +474,6 @@ void RewriteInstructionToUseNewBase(const SCEVHandle &NewBase, SCEVExpander &Rewriter, Loop *L, Pass *P); - - // Sort by the Base field. - bool operator<(const BasedUser &BU) const { return Base < BU.Base; } - void dump() const; }; } @@ -878,9 +874,8 @@ // Sort by the base value, so that all IVs with identical bases are next to // each other. - std::sort(UsersToProcess.begin(), UsersToProcess.end()); while (!UsersToProcess.empty()) { - SCEVHandle Base = UsersToProcess.front().Base; + SCEVHandle Base = UsersToProcess.back().Base; DEBUG(std::cerr << " INSERTING code for BASE = " << *Base << ":\n"); @@ -901,8 +896,9 @@ // Emit the code to add the immediate offset to the Phi value, just before // the instructions that we identified as using this stride and base. - while (!UsersToProcess.empty() && UsersToProcess.front().Base == Base) { - BasedUser &User = UsersToProcess.front(); + unsigned ScanPos = 0; + do { + BasedUser &User = UsersToProcess.back(); // If this instruction wants to use the post-incremented value, move it // after the post-inc and use its value instead of the PHI. @@ -933,9 +929,19 @@ // if we just replaced the last use of that value. DeadInsts.insert(cast(User.OperandValToReplace)); - UsersToProcess.erase(UsersToProcess.begin()); + UsersToProcess.pop_back(); ++NumReduced; - } + + // If there are any more users to process with the same base, move one of + // them to the end of the list so that we will process it. + if (!UsersToProcess.empty()) { + for (unsigned e = UsersToProcess.size(); ScanPos != e; ++ScanPos) + if (UsersToProcess[ScanPos].Base == Base) { + std::swap(UsersToProcess[ScanPos], UsersToProcess.back()); + break; + } + } + } while (!UsersToProcess.empty() && UsersToProcess.back().Base == Base); // TODO: Next, find out which base index is the most common, pull it out. } From lattner at cs.uiuc.edu Tue Oct 11 13:41:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 11 Oct 2005 13:41:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200510111841.NAA24627@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.67 -> 1.68 --- Log message: Fix (hopefully the last) issue where LSR is nondeterminstic. When pulling out CSE's of base expressions it could build a result whose order was nondet. --- Diffs of the changes: (+14 -8) LoopStrengthReduce.cpp | 22 ++++++++++++++-------- 1 files changed, 14 insertions(+), 8 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.67 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.68 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.67 Tue Oct 11 13:30:57 2005 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue Oct 11 13:41:04 2005 @@ -715,6 +715,10 @@ // If any subexpressions are used Uses.size() times, they are common. std::map SubExpressionUseCounts; + // UniqueSubExprs - Keep track of all of the subexpressions we see in the + // order we see them. + std::vector UniqueSubExprs; + std::vector SubExprs; for (unsigned i = 0; i != NumUses; ++i) { // If the base is zero (which is common), return zero now, there are no @@ -725,22 +729,24 @@ SeparateSubExprs(SubExprs, Uses[i].Base); // Add one to SubExpressionUseCounts for each subexpr present. for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) - SubExpressionUseCounts[SubExprs[j]]++; + if (++SubExpressionUseCounts[SubExprs[j]] == 1) + UniqueSubExprs.push_back(SubExprs[j]); SubExprs.clear(); } - - // Now that we know how many times each is used, build Result. - for (std::map::iterator I = - SubExpressionUseCounts.begin(), E = SubExpressionUseCounts.end(); - I != E; ) + // Now that we know how many times each is used, build Result. Iterate over + // UniqueSubexprs so that we have a stable ordering. + for (unsigned i = 0, e = UniqueSubExprs.size(); i != e; ++i) { + std::map::iterator I = + SubExpressionUseCounts.find(UniqueSubExprs[i]); + assert(I != SubExpressionUseCounts.end() && "Entry not found?"); if (I->second == NumUses) { // Found CSE! Result = SCEVAddExpr::get(Result, I->first); - ++I; } else { // Remove non-cse's from SubExpressionUseCounts. - SubExpressionUseCounts.erase(I++); + SubExpressionUseCounts.erase(I); } + } // If we found no CSE's, return now. if (Result == Zero) return Result; From lattner at cs.uiuc.edu Tue Oct 11 13:42:37 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 11 Oct 2005 13:42:37 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll Message-ID: <200510111842.NAA24669@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LoopStrengthReduce: dont_reduce_bytes.ll updated: 1.3 -> 1.4 --- Log message: this passes with the change in predicate --- Diffs of the changes: (+0 -2) dont_reduce_bytes.ll | 2 -- 1 files changed, 2 deletions(-) Index: llvm/test/Regression/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll diff -u llvm/test/Regression/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll:1.3 llvm/test/Regression/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll:1.4 --- llvm/test/Regression/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll:1.3 Tue Oct 11 13:28:48 2005 +++ llvm/test/Regression/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll Tue Oct 11 13:42:26 2005 @@ -3,8 +3,6 @@ ; RUN: llvm-as < %s | opt -loop-reduce -disable-output -; XFAIL: * - declare bool %pred(int) void %test(sbyte* %PTR) { From jlaskey at apple.com Wed Oct 12 07:09:21 2005 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 12 Oct 2005 07:09:21 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineFunction.cpp Message-ID: <200510121209.HAA25380@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineFunction.cpp updated: 1.80 -> 1.81 --- Log message: Added graphviz/gv support for MF. --- Diffs of the changes: (+22 -0) MachineFunction.cpp | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+) Index: llvm/lib/CodeGen/MachineFunction.cpp diff -u llvm/lib/CodeGen/MachineFunction.cpp:1.80 llvm/lib/CodeGen/MachineFunction.cpp:1.81 --- llvm/lib/CodeGen/MachineFunction.cpp:1.80 Wed Aug 31 17:34:59 2005 +++ llvm/lib/CodeGen/MachineFunction.cpp Wed Oct 12 07:09:05 2005 @@ -25,6 +25,7 @@ #include "llvm/Instructions.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/GraphWriter.h" +#include "llvm/Config/config.h" #include #include #include @@ -206,6 +207,7 @@ void MachineFunction::viewCFG() const { +#ifndef NDEBUG std::string Filename = "/tmp/cfg." + getFunction()->getName() + ".dot"; std::cerr << "Writing '" << Filename << "'... "; std::ofstream F(Filename.c_str()); @@ -219,6 +221,17 @@ F.close(); std::cerr << "\n"; +#ifdef HAVE_GRAPHVIZ + std::cerr << "Running 'Graphviz' program... " << std::flush; + if (system((LLVM_PATH_GRAPHVIZ " " + Filename).c_str())) { + std::cerr << "Error viewing graph: 'Graphviz' not in path?\n"; + } else { + system(("rm " + Filename).c_str()); + return; + } +#endif // HAVE_GRAPHVIZ + +#ifdef HAVE_GV std::cerr << "Running 'dot' program... " << std::flush; if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename + " > /tmp/cfg.tempgraph.ps").c_str())) { @@ -228,6 +241,15 @@ system("gv /tmp/cfg.tempgraph.ps"); } system(("rm " + Filename + " /tmp/cfg.tempgraph.ps").c_str()); + return; +#endif // HAVE_GV +#endif // NDEBUG + std::cerr << "MachineFunction::viewCFG is only available in debug builds on " + << "systems with Graphviz or gv!\n"; + +#ifndef NDEBUG + system(("rm " + Filename).c_str()); +#endif } void MachineFunction::viewCFGOnly() const From jlaskey at apple.com Wed Oct 12 12:24:55 2005 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 12 Oct 2005 12:24:55 -0500 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Benchmarks/mediabench/mpeg2/mpeg2dec/mpeg2dec.c Message-ID: <200510121724.MAA12372@zion.cs.uiuc.edu> Changes in directory llvm-test/MultiSource/Benchmarks/mediabench/mpeg2/mpeg2dec: mpeg2dec.c updated: 1.1 -> 1.2 --- Log message: Missing header file was causing lseek to receive incorrect args. Exposed by the scheduler. --- Diffs of the changes: (+1 -0) mpeg2dec.c | 1 + 1 files changed, 1 insertion(+) Index: llvm-test/MultiSource/Benchmarks/mediabench/mpeg2/mpeg2dec/mpeg2dec.c diff -u llvm-test/MultiSource/Benchmarks/mediabench/mpeg2/mpeg2dec/mpeg2dec.c:1.1 llvm-test/MultiSource/Benchmarks/mediabench/mpeg2/mpeg2dec/mpeg2dec.c:1.2 --- llvm-test/MultiSource/Benchmarks/mediabench/mpeg2/mpeg2dec/mpeg2dec.c:1.1 Tue Jan 11 12:05:32 2005 +++ llvm-test/MultiSource/Benchmarks/mediabench/mpeg2/mpeg2dec/mpeg2dec.c Wed Oct 12 12:24:43 2005 @@ -32,6 +32,7 @@ #include #include #include +#include #define GLOBAL #include "config.h" From jlaskey at apple.com Wed Oct 12 13:29:47 2005 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 12 Oct 2005 13:29:47 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200510121829.NAA12731@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.35 -> 1.36 --- Log message: Finally committing to the new scheduler. Still -sched=none by default. --- Diffs of the changes: (+125 -249) ScheduleDAG.cpp | 374 ++++++++++++++++++-------------------------------------- 1 files changed, 125 insertions(+), 249 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.35 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.36 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.35 Sun Oct 9 00:58:56 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Wed Oct 12 13:29:35 2005 @@ -190,13 +190,16 @@ }; //===----------------------------------------------------------------------===// +// Forward +class NodeInfo; +typedef std::vector NIVector; +typedef std::vector::iterator NIIterator; //===----------------------------------------------------------------------===// /// /// Node group - This struct is used to manage flagged node groups. /// -class NodeInfo; -class NodeGroup : public std::vector { +class NodeGroup : public NIVector { private: int Pending; // Number of visits pending before // adding to order @@ -232,7 +235,10 @@ unsigned Slot; // Node's time slot NodeGroup *Group; // Grouping information unsigned VRBase; // Virtual register base - +#ifndef NDEBUG + unsigned Preorder; // Index before scheduling +#endif + // Ctor. NodeInfo(SDNode *N = NULL) : Pending(0) @@ -264,7 +270,6 @@ else return Pending += I; } }; -typedef std::vector::iterator NIIterator; //===----------------------------------------------------------------------===// @@ -383,10 +388,9 @@ unsigned NodeCount; // Number of nodes in DAG NodeInfo *Info; // Info for nodes being scheduled std::map Map; // Map nodes to info - std::vector Ordering; // Emit ordering of nodes + NIVector Ordering; // Emit ordering of nodes ResourceTally Tally; // Resource usage tally unsigned NSlots; // Total latency - std::map VRMap; // Node to VR map static const unsigned NotFound = ~0U; // Search marker public: @@ -396,7 +400,7 @@ : BB(bb), DAG(D), TM(D.getTarget()), TII(*TM.getInstrInfo()), MRI(*TM.getRegisterInfo()), RegMap(BB->getParent()->getSSARegMap()), ConstPool(BB->getParent()->getConstantPool()), - NSlots(0) { + NodeCount(0), Info(NULL), Map(), Tally(), NSlots(0) { assert(&TII && "Target doesn't provide instr info?"); assert(&MRI && "Target doesn't provide register info?"); } @@ -427,7 +431,9 @@ void IncludeNode(NodeInfo *NI); void VisitAll(); void Schedule(); - void GatherNodeInfo(); + void IdentifyGroups(); + void GatherSchedulingInfo(); + void PrepareNodeInfo(); bool isStrongDependency(NodeInfo *A, NodeInfo *B); bool isWeakDependency(NodeInfo *A, NodeInfo *B); void ScheduleBackward(); @@ -439,8 +445,8 @@ unsigned CreateVirtualRegisters(MachineInstr *MI, unsigned NumResults, const TargetInstrDescriptor &II); - unsigned EmitDAG(SDOperand A); + void printChanges(unsigned Index); void printSI(std::ostream &O, NodeInfo *NI) const; void print(std::ostream &O) const; inline void dump(const char *tag) const { std::cerr << tag; dump(); } @@ -635,28 +641,34 @@ } } -/// GatherNodeInfo - Get latency and resource information about each node. -/// -void SimpleSched::GatherNodeInfo() { - // Allocate node information - Info = new NodeInfo[NodeCount]; - // Get base of all nodes table - SelectionDAG::allnodes_iterator AllNodes = DAG.allnodes_begin(); - - // For each node being scheduled +/// IdentifyGroups - Put flagged nodes into groups. +/// +void SimpleSched::IdentifyGroups() { for (unsigned i = 0, N = NodeCount; i < N; i++) { - // Get next node from DAG all nodes table - SDNode *Node = AllNodes[i]; - // Fast reference to node schedule info NodeInfo* NI = &Info[i]; - // Set up map - Map[Node] = NI; - // Set node - NI->Node = Node; - // Set pending visit count - NI->setPending(Node->use_size()); - + SDNode *Node = NI->Node; + + // For each operand (in reverse to only look at flags) + for (unsigned N = Node->getNumOperands(); 0 < N--;) { + // Get operand + SDOperand Op = Node->getOperand(N); + // No more flags to walk + if (Op.getValueType() != MVT::Flag) break; + // Add to node group + NodeGroup::Add(getNI(Op.Val), NI); + } + } +} + +/// GatherSchedulingInfo - Get latency and resource information about each node. +/// +void SimpleSched::GatherSchedulingInfo() { + for (unsigned i = 0, N = NodeCount; i < N; i++) { + NodeInfo* NI = &Info[i]; + SDNode *Node = NI->Node; + MVT::ValueType VT = Node->getValueType(0); + if (Node->isTargetOpcode()) { MachineOpCode TOpc = Node->getTargetOpcode(); // FIXME: This is an ugly (but temporary!) hack to test the scheduler @@ -701,21 +713,28 @@ // Sum up all the latencies for max tally size NSlots += NI->Latency; } +} - // Put flagged nodes into groups +/// PrepareNodeInfo - Set up the basic minimum node info for scheduling. +/// +void SimpleSched::PrepareNodeInfo() { + // Allocate node information + Info = new NodeInfo[NodeCount]; + // Get base of all nodes table + SelectionDAG::allnodes_iterator AllNodes = DAG.allnodes_begin(); + + // For each node being scheduled for (unsigned i = 0, N = NodeCount; i < N; i++) { + // Get next node from DAG all nodes table + SDNode *Node = AllNodes[i]; + // Fast reference to node schedule info NodeInfo* NI = &Info[i]; - SDNode *Node = NI->Node; - - // For each operand (in reverse to only look at flags) - for (unsigned N = Node->getNumOperands(); 0 < N--;) { - // Get operand - SDOperand Op = Node->getOperand(N); - // No more flags to walk - if (Op.getValueType() != MVT::Flag) break; - // Add to node group - NodeGroup::Add(getNI(Op.Val), NI); - } + // Set up map + Map[Node] = NI; + // Set node + NI->Node = Node; + // Set pending visit count + NI->setPending(Node->use_size()); } } @@ -784,7 +803,7 @@ for (; j < N; j++) { // Get following instruction NodeInfo *Other = Ordering[j]; - // Should we look further + // Should we look further (remember slots are in reverse time) if (Slot >= Other->Slot) break; // Shuffle other into ordering Ordering[j - 1] = Other; @@ -837,7 +856,7 @@ // Insert sort based on slot j = i; for (; 0 < j--;) { - // Get following instruction + // Get prior instruction NodeInfo *Other = Ordering[j]; // Should we look further if (Slot >= Other->Slot) break; @@ -856,11 +875,8 @@ for (unsigned i = 0, N = Ordering.size(); i < N; i++) { // Get the scheduling info NodeInfo *NI = Ordering[i]; -#if 0 // Iterate through nodes NodeGroupIterator NGI(Ordering[i]); - while (NodeInfo *NI = NGI.next()) EmitNode(NI); -#else if (NI->isInGroup()) { if (NI->isGroupLeader()) { NodeGroupIterator NGI(Ordering[i]); @@ -869,7 +885,6 @@ } else { EmitNode(NI); } -#endif } } @@ -1055,228 +1070,89 @@ NI->VRBase = VRBase; } -/// EmitDag - Generate machine code for an operand and needed dependencies. +/// Schedule - Order nodes according to selected style. /// -unsigned SimpleSched::EmitDAG(SDOperand Op) { - std::map::iterator OpI = VRMap.lower_bound(Op.Val); - if (OpI != VRMap.end() && OpI->first == Op.Val) - return OpI->second + Op.ResNo; - unsigned &OpSlot = VRMap.insert(OpI, std::make_pair(Op.Val, 0))->second; - - unsigned ResultReg = 0; - if (Op.isTargetOpcode()) { - unsigned Opc = Op.getTargetOpcode(); - const TargetInstrDescriptor &II = TII.get(Opc); +void SimpleSched::Schedule() { + // Number the nodes + NodeCount = DAG.allnodes_size(); + // Set up minimum info for scheduling. + PrepareNodeInfo(); + // Construct node groups for flagged nodes + IdentifyGroups(); + // Breadth first walk of DAG + VisitAll(); - unsigned NumResults = CountResults(Op.Val); - unsigned NodeOperands = CountOperands(Op.Val); - unsigned NumMIOperands = NodeOperands + NumResults; #ifndef NDEBUG - assert((unsigned(II.numOperands) == NumMIOperands || II.numOperands == -1)&& - "#operands for dag node doesn't match .td file!"); -#endif - - // Create the new machine instruction. - MachineInstr *MI = new MachineInstr(Opc, NumMIOperands, true, true); - - // Add result register values for things that are defined by this - // instruction. - if (NumResults) ResultReg = CreateVirtualRegisters(MI, NumResults, II); + static unsigned Count = 0; + Count++; + for (unsigned i = 0, N = Ordering.size(); i < N; i++) { + NodeInfo *NI = Ordering[i]; + NI->Preorder = i; + } +#endif + + // Don't waste time if is only entry and return + if (NodeCount > 3 && ScheduleStyle != noScheduling) { + // Get latency and resource requirements + GatherSchedulingInfo(); - // If there is a token chain operand, emit it first, as a hack to get avoid - // really bad cases. - if (Op.getNumOperands() > NodeOperands && - Op.getOperand(NodeOperands).getValueType() == MVT::Other) { - EmitDAG(Op.getOperand(NodeOperands)); - } + // Push back long instructions and critical path + ScheduleBackward(); - // Emit all of the actual operands of this instruction, adding them to the - // instruction as appropriate. - for (unsigned i = 0; i != NodeOperands; ++i) { - if (Op.getOperand(i).isTargetOpcode()) { - // Note that this case is redundant with the final else block, but we - // include it because it is the most common and it makes the logic - // simpler here. - assert(Op.getOperand(i).getValueType() != MVT::Other && - Op.getOperand(i).getValueType() != MVT::Flag && - "Chain and flag operands should occur at end of operand list!"); - - unsigned VReg = EmitDAG(Op.getOperand(i)); - MI->addRegOperand(VReg, MachineOperand::Use); - - // Verify that it is right. - assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); - assert(II.OpInfo[i+NumResults].RegClass && - "Don't have operand info for this instruction!"); + // Pack instructions to maximize resource utilization + ScheduleForward(); + } + + DEBUG(printChanges(Count)); + + // Emit in scheduled order + EmitAll(); +} + +/// printChanges - Hilight changes in order caused by scheduling. +/// +void SimpleSched::printChanges(unsigned Index) { #ifndef NDEBUG - if (RegMap->getRegClass(VReg) != II.OpInfo[i+NumResults].RegClass) { - std::cerr << "OP: "; - Op.getOperand(i).Val->dump(&DAG); std::cerr << "\nUSE: "; - Op.Val->dump(&DAG); std::cerr << "\n"; + // Get the ordered node count + unsigned N = Ordering.size(); + // Determine if any changes + unsigned i = 0; + for (; i < N; i++) { + NodeInfo *NI = Ordering[i]; + if (NI->Preorder != i) break; + } + + if (i < N) { + std::cerr << Index << ". New Ordering\n"; + + for (i = 0; i < N; i++) { + NodeInfo *NI = Ordering[i]; + std::cerr << " " << NI->Preorder << ". "; + printSI(std::cerr, NI); + std::cerr << "\n"; + if (NI->isGroupLeader()) { + NodeGroup *Group = NI->Group; + for (NIIterator NII = Group->begin(), E = Group->end(); + NII != E; NII++) { + std::cerr << " "; + printSI(std::cerr, *NII); + std::cerr << "\n"; } -#endif - assert(RegMap->getRegClass(VReg) == II.OpInfo[i+NumResults].RegClass && - "Register class of operand and regclass of use don't agree!"); - } else if (ConstantSDNode *C = - dyn_cast(Op.getOperand(i))) { - MI->addZeroExtImm64Operand(C->getValue()); - } else if (RegisterSDNode*R =dyn_cast(Op.getOperand(i))) { - MI->addRegOperand(R->getReg(), MachineOperand::Use); - } else if (GlobalAddressSDNode *TGA = - dyn_cast(Op.getOperand(i))) { - MI->addGlobalAddressOperand(TGA->getGlobal(), false, 0); - } else if (BasicBlockSDNode *BB = - dyn_cast(Op.getOperand(i))) { - MI->addMachineBasicBlockOperand(BB->getBasicBlock()); - } else if (FrameIndexSDNode *FI = - dyn_cast(Op.getOperand(i))) { - MI->addFrameIndexOperand(FI->getIndex()); - } else if (ConstantPoolSDNode *CP = - dyn_cast(Op.getOperand(i))) { - unsigned Idx = ConstPool->getConstantPoolIndex(CP->get()); - MI->addConstantPoolIndexOperand(Idx); - } else if (ExternalSymbolSDNode *ES = - dyn_cast(Op.getOperand(i))) { - MI->addExternalSymbolOperand(ES->getSymbol(), false); - } else { - assert(Op.getOperand(i).getValueType() != MVT::Other && - Op.getOperand(i).getValueType() != MVT::Flag && - "Chain and flag operands should occur at end of operand list!"); - unsigned VReg = EmitDAG(Op.getOperand(i)); - MI->addRegOperand(VReg, MachineOperand::Use); - - // Verify that it is right. - assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); - assert(II.OpInfo[i+NumResults].RegClass && - "Don't have operand info for this instruction!"); - assert(RegMap->getRegClass(VReg) == II.OpInfo[i+NumResults].RegClass && - "Register class of operand and regclass of use don't agree!"); - } - } - - // Finally, if this node has any flag operands, we *must* emit them last, to - // avoid emitting operations that might clobber the flags. - if (Op.getNumOperands() > NodeOperands) { - unsigned i = NodeOperands; - if (Op.getOperand(i).getValueType() == MVT::Other) - ++i; // the chain is already selected. - for (unsigned N = Op.getNumOperands(); i < N; i++) { - assert(Op.getOperand(i).getValueType() == MVT::Flag && - "Must be flag operands!"); - EmitDAG(Op.getOperand(i)); } } - - // Now that we have emitted all operands, emit this instruction itself. - if ((II.Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION) == 0) { - BB->insert(BB->end(), MI); - } else { - // Insert this instruction into the end of the basic block, potentially - // taking some custom action. - BB = DAG.getTargetLoweringInfo().InsertAtEndOfBasicBlock(MI, BB); - } } else { - switch (Op.getOpcode()) { - default: - Op.Val->dump(); - assert(0 && "This target-independent node should have been selected!"); - case ISD::EntryToken: break; - case ISD::TokenFactor: - for (unsigned i = 0, N = Op.getNumOperands(); i < N; i++) { - EmitDAG(Op.getOperand(i)); - } - break; - case ISD::CopyToReg: { - SDOperand FlagOp; FlagOp.ResNo = 0; - if (Op.getNumOperands() == 4) { - FlagOp = Op.getOperand(3); - } - if (Op.getOperand(0).Val != FlagOp.Val) { - EmitDAG(Op.getOperand(0)); // Emit the chain. - } - unsigned Val = EmitDAG(Op.getOperand(2)); - if (FlagOp.Val) { - EmitDAG(FlagOp); - } - MRI.copyRegToReg(*BB, BB->end(), - cast(Op.getOperand(1))->getReg(), Val, - RegMap->getRegClass(Val)); - break; - } - case ISD::CopyFromReg: { - EmitDAG(Op.getOperand(0)); // Emit the chain. - unsigned SrcReg = cast(Op.getOperand(1))->getReg(); - - // If the input is already a virtual register, just use it. - if (MRegisterInfo::isVirtualRegister(SrcReg)) { - ResultReg = SrcReg; - break; - } - - // Figure out the register class to create for the destreg. - const TargetRegisterClass *TRC = 0; - - // Pick the register class of the right type that contains this physreg. - for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(), - E = MRI.regclass_end(); I != E; ++I) - if ((*I)->getType() == Op.Val->getValueType(0) && - (*I)->contains(SrcReg)) { - TRC = *I; - break; - } - assert(TRC && "Couldn't find register class for reg copy!"); - - // Create the reg, emit the copy. - ResultReg = RegMap->createVirtualRegister(TRC); - MRI.copyRegToReg(*BB, BB->end(), ResultReg, SrcReg, TRC); - break; - } - } - } - - OpSlot = ResultReg; - return ResultReg+Op.ResNo; -} - -/// Schedule - Order nodes according to selected style. -/// -void SimpleSched::Schedule() { - switch (ScheduleStyle) { - case simpleScheduling: - // Number the nodes - NodeCount = DAG.allnodes_size(); - // Don't waste time if is only entry and return - if (NodeCount > 3) { - // Get latency and resource requirements - GatherNodeInfo(); - // Breadth first walk of DAG - VisitAll(); - DEBUG(dump("Pre-")); - // Push back long instructions and critical path - ScheduleBackward(); - DEBUG(dump("Mid-")); - // Pack instructions to maximize resource utilization - ScheduleForward(); - DEBUG(dump("Post-")); - // Emit in scheduled order - EmitAll(); - break; - } // fall thru - case noScheduling: - // Emit instructions in using a DFS from the exit root - EmitDAG(DAG.getRoot()); - break; + std::cerr << Index << ". No Changes\n"; } +#endif } /// printSI - Print schedule info. /// void SimpleSched::printSI(std::ostream &O, NodeInfo *NI) const { #ifndef NDEBUG - using namespace std; SDNode *Node = NI->Node; O << " " - << hex << Node + << std::hex << Node << std::dec << ", RS=" << NI->ResourceSet << ", Lat=" << NI->Latency << ", Slot=" << NI->Slot From natebegeman at mac.com Wed Oct 12 15:40:51 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 12 Oct 2005 15:40:51 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510122040.PAA23336@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.32 -> 1.33 --- Log message: More cool stuff for the dag combiner. We can now finally handle things like turning: _foo: fctiwz f0, f1 stfd f0, -8(r1) lwz r2, -4(r1) rlwinm r3, r2, 0, 16, 31 blr into _foo: fctiwz f0,f1 stfd f0,-8(r1) lhz r3,-2(r1) blr Also removed an unncessary constraint from sra -> srl conversion, which should take care of hte only reason we would ever need to handle sra in MaskedValueIsZero, AFAIK. --- Diffs of the changes: (+22 -3) DAGCombiner.cpp | 25 ++++++++++++++++++++++--- 1 files changed, 22 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.32 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.33 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.32 Tue Oct 11 12:56:34 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Oct 12 15:40:40 2005 @@ -279,8 +279,6 @@ // Bit counting instructions can not set the high bits of the result // register. The max number of bits sets depends on the input. return (Mask & (MVT::getSizeInBits(Op.getValueType())*2-1)) == 0; - - // TODO we could handle some SRA cases here. default: break; } return false; @@ -1034,7 +1032,7 @@ if (N1C && N1C->isNullValue()) return N0; // If the sign bit is known to be zero, switch this to a SRL. - if (N1C && MaskedValueIsZero(N0, (1ULL << (OpSizeInBits-1)), TLI)) + if (MaskedValueIsZero(N0, (1ULL << (OpSizeInBits-1)), TLI)) return DAG.getNode(ISD::SRL, VT, N0, N1); return SDOperand(); } @@ -1196,6 +1194,14 @@ // fold (sext (sext x)) -> (sext x) if (N0.getOpcode() == ISD::SIGN_EXTEND) return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0)); + // fold (sext (load x)) -> (sextload x) + if (N0.getOpcode() == ISD::LOAD && N0.Val->hasNUsesOfValue(1, 0)) { + SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), + N0.getOperand(1), N0.getOperand(2), + N0.getValueType()); + CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); + return CombineTo(N, ExtLoad); + } return SDOperand(); } @@ -1292,6 +1298,19 @@ // and the truncate return N0.getOperand(0); } + // fold (truncate (load x)) -> (smaller load x) + if (N0.getOpcode() == ISD::LOAD && N0.Val->hasNUsesOfValue(1, 0)) { + assert(MVT::getSizeInBits(N0.getValueType()) > MVT::getSizeInBits(VT) && + "Cannot truncate to larger type!"); + MVT::ValueType PtrType = N0.getOperand(1).getValueType(); + uint64_t PtrOff = + (MVT::getSizeInBits(N0.getValueType()) - MVT::getSizeInBits(VT)) / 8; + SDOperand NewPtr = DAG.getNode(ISD::ADD, PtrType, N0.getOperand(1), + DAG.getConstant(PtrOff, PtrType)); + SDOperand Load = DAG.getLoad(VT, N0.getOperand(0), NewPtr,N0.getOperand(2)); + CombineTo(N0.Val, Load, Load.getOperand(0)); + return CombineTo(N, Load); + } return SDOperand(); } From natebegeman at mac.com Wed Oct 12 18:19:05 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 12 Oct 2005 18:19:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510122319.SAA08147@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.33 -> 1.34 --- Log message: Fix a potential bug with two combine-to's back to back that chris pointed out, where after the first CombineTo() call, the node the second CombineTo wishes to replace may no longer exist. Fix a very real bug with the truncated load optimization on little endian targets, which do not need a byte offset added to the load. --- Diffs of the changes: (+14 -4) DAGCombiner.cpp | 18 ++++++++++++++---- 1 files changed, 14 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.33 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.34 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.33 Wed Oct 12 15:40:40 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Oct 12 18:18:53 2005 @@ -1194,13 +1194,17 @@ // fold (sext (sext x)) -> (sext x) if (N0.getOpcode() == ISD::SIGN_EXTEND) return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0)); + // fold (sext (sextload x)) -> (sextload x) + if (N0.getOpcode() == ISD::SEXTLOAD && VT == N0.getValueType()) + return N0; // fold (sext (load x)) -> (sextload x) if (N0.getOpcode() == ISD::LOAD && N0.Val->hasNUsesOfValue(1, 0)) { SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), N0.getValueType()); CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); - return CombineTo(N, ExtLoad); + WorkList.push_back(N); + return SDOperand(); } return SDOperand(); } @@ -1303,13 +1307,19 @@ assert(MVT::getSizeInBits(N0.getValueType()) > MVT::getSizeInBits(VT) && "Cannot truncate to larger type!"); MVT::ValueType PtrType = N0.getOperand(1).getValueType(); + // For big endian targets, we need to add an offset to the pointer to load + // the correct bytes. For little endian systems, we merely need to read + // fewer bytes from the same pointer. uint64_t PtrOff = (MVT::getSizeInBits(N0.getValueType()) - MVT::getSizeInBits(VT)) / 8; - SDOperand NewPtr = DAG.getNode(ISD::ADD, PtrType, N0.getOperand(1), - DAG.getConstant(PtrOff, PtrType)); + SDOperand NewPtr = TLI.isLittleEndian() ? N0.getOperand(1) : + DAG.getNode(ISD::ADD, PtrType, N0.getOperand(1), + DAG.getConstant(PtrOff, PtrType)); + WorkList.push_back(NewPtr.Val); SDOperand Load = DAG.getLoad(VT, N0.getOperand(0), NewPtr,N0.getOperand(2)); CombineTo(N0.Val, Load, Load.getOperand(0)); - return CombineTo(N, Load); + WorkList.push_back(N); + return SDOperand(); } return SDOperand(); } From natebegeman at mac.com Wed Oct 12 22:10:58 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 12 Oct 2005 22:10:58 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200510130310.WAA08955@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.62 -> 1.63 --- Log message: SimplifySelectCC is dead --- Diffs of the changes: (+0 -6) SelectionDAG.h | 6 ------ 1 files changed, 6 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.62 llvm/include/llvm/CodeGen/SelectionDAG.h:1.63 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.62 Fri Sep 30 14:27:01 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Wed Oct 12 22:10:46 2005 @@ -358,12 +358,6 @@ SDOperand SimplifySetCC(MVT::ValueType VT, SDOperand N1, SDOperand N2, ISD::CondCode Cond); - /// SimplifySelectCC - Try to simplify a select_cc built with the specified - /// operands and cc. This can be used to simplify both the select_cc node, - /// and a select node whose first operand is a setcc. - SDOperand SimplifySelectCC(SDOperand N1, SDOperand N2, SDOperand N3, - SDOperand N4, ISD::CondCode CC); - // Maps to auto-CSE operations. std::map, SDNode *> NullaryOps; std::map >, From natebegeman at mac.com Wed Oct 12 22:11:40 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 12 Oct 2005 22:11:40 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp LegalizeDAG.cpp SelectionDAG.cpp Message-ID: <200510130311.WAA08979@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.34 -> 1.35 LegalizeDAG.cpp updated: 1.194 -> 1.195 SelectionDAG.cpp updated: 1.205 -> 1.206 --- Log message: Move some Legalize functionality over to the DAGCombiner where it belongs. Kill some dead code. --- Diffs of the changes: (+79 -149) DAGCombiner.cpp | 74 +++++++++++++++++++++++++++++++ LegalizeDAG.cpp | 23 ++------- SelectionDAG.cpp | 131 ------------------------------------------------------- 3 files changed, 79 insertions(+), 149 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.34 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.35 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.34 Wed Oct 12 18:18:53 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Oct 12 22:11:28 2005 @@ -451,6 +451,9 @@ } SDOperand DAGCombiner::visitTokenFactor(SDNode *N) { + std::vector Ops; + bool Changed = false; + // If the token factor has two operands and one is the entry token, replace // the token factor with the other operand. if (N->getNumOperands() == 2) { @@ -459,6 +462,19 @@ if (N->getOperand(1).getOpcode() == ISD::EntryToken) return N->getOperand(0); } + // fold (tokenfactor (tokenfactor)) -> tokenfactor + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + SDOperand Op = N->getOperand(i); + if (Op.getOpcode() == ISD::TokenFactor && Op.hasOneUse()) { + Changed = true; + for (unsigned j = 0, e = Op.getNumOperands(); j != e; ++j) + Ops.push_back(Op.getOperand(j)); + } else { + Ops.push_back(Op); + } + } + if (Changed) + return DAG.getNode(ISD::TokenFactor, MVT::Other, Ops); return SDOperand(); } @@ -782,6 +798,40 @@ WorkList.push_back(ANDNode.Val); return DAG.getNode(N0.getOpcode(), VT, ANDNode, N0.getOperand(1)); } + // fold (zext_inreg (extload x)) -> (zextload x) + if (N1C && N0.getOpcode() == ISD::EXTLOAD) { + MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); + // If the type of the zext_inreg and the extload match, and we're running + // before Legalize, or the resulting zextload is legal on the target, then + // go ahead and do the fold. + if ((N1C->getValue() == (1ULL << MVT::getSizeInBits(EVT))-1) && + (!AfterLegalize || + TargetLowering::Legal == TLI.getOperationAction(ISD::ZEXTLOAD, EVT))) { + SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), + N0.getOperand(1), N0.getOperand(2), + EVT); + CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); + WorkList.push_back(N); + return SDOperand(); + } + } + // fold (zext_inreg (sextload x)) -> (zextload x) iff load has one use + if (N1C && N0.getOpcode() == ISD::SEXTLOAD && N0.Val->hasNUsesOfValue(1, 0)) { + MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); + // If the type of the zext_inreg and the extload match, and we're running + // before Legalize, or the resulting zextload is legal on the target, then + // go ahead and do the fold. + if ((N1C->getValue() == (1ULL << MVT::getSizeInBits(EVT))-1) && + (!AfterLegalize || + TargetLowering::Legal == TLI.getOperationAction(ISD::ZEXTLOAD, EVT))) { + SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), + N0.getOperand(1), N0.getOperand(2), + EVT); + CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); + WorkList.push_back(N); + return SDOperand(); + } + } return SDOperand(); } @@ -1272,6 +1322,30 @@ return DAG.getNode(ISD::SRA, N0.getValueType(), N0.getOperand(0), N0.getOperand(1)); } + // fold (sext_inreg (extload x)) -> (sextload x) + if (N0.getOpcode() == ISD::EXTLOAD && + EVT == cast(N0.getOperand(3))->getVT() && + (!AfterLegalize || + (TargetLowering::Legal == TLI.getOperationAction(ISD::SEXTLOAD, EVT)))) { + SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), + N0.getOperand(1), N0.getOperand(2), + EVT); + CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); + WorkList.push_back(N); + return SDOperand(); + } + // fold (sext_inreg (zextload x)) -> (sextload x) iff load has one use + if (N0.getOpcode() == ISD::ZEXTLOAD && N0.Val->hasNUsesOfValue(1, 0) && + EVT == cast(N0.getOperand(3))->getVT() && + (!AfterLegalize || + (TargetLowering::Legal == TLI.getOperationAction(ISD::SEXTLOAD, EVT)))) { + SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), + N0.getOperand(1), N0.getOperand(2), + EVT); + CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); + WorkList.push_back(N); + return SDOperand(); + } return SDOperand(); } Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.194 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.195 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.194 Thu Oct 6 12:39:10 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Oct 12 22:11:28 2005 @@ -635,18 +635,11 @@ case ISD::TokenFactor: { std::vector Ops; bool Changed = false; + // Legalize the operands for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { SDOperand Op = Node->getOperand(i); - // Fold single-use TokenFactor nodes into this token factor as we go. - // FIXME: This is something that the DAGCombiner should do!! - if (Op.getOpcode() == ISD::TokenFactor && Op.hasOneUse()) { - Changed = true; - for (unsigned j = 0, e = Op.getNumOperands(); j != e; ++j) - Ops.push_back(LegalizeOp(Op.getOperand(j))); - } else { - Ops.push_back(LegalizeOp(Op)); // Legalize the operands - Changed |= Ops[i] != Op; - } + Ops.push_back(LegalizeOp(Op)); + Changed |= Ops[i] != Op; } if (Changed) Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Ops); @@ -2352,14 +2345,8 @@ case ISD::LOAD: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. - // FIXME: When the DAG combiner exists, change this to use EXTLOAD! - if (MVT::isInteger(NVT)) - Result = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Tmp1, Tmp2, - Node->getOperand(2), VT); - else - Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp1, Tmp2, - Node->getOperand(2), VT); - + Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp1, Tmp2, + Node->getOperand(2), VT); // Remember that we legalized the chain. AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); break; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.205 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.206 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.205 Mon Oct 10 11:49:22 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Oct 12 22:11:28 2005 @@ -779,134 +779,6 @@ return SDOperand(); } -SDOperand SelectionDAG::SimplifySelectCC(SDOperand N1, SDOperand N2, - SDOperand N3, SDOperand N4, - ISD::CondCode CC) { - MVT::ValueType VT = N3.getValueType(); - ConstantSDNode *N1C = dyn_cast(N1.Val); - ConstantSDNode *N2C = dyn_cast(N2.Val); - ConstantSDNode *N3C = dyn_cast(N3.Val); - ConstantSDNode *N4C = dyn_cast(N4.Val); - - // Check to see if we can simplify the select into an fabs node - if (ConstantFPSDNode *CFP = dyn_cast(N2)) { - // Allow either -0.0 or 0.0 - if (CFP->getValue() == 0.0) { - // select (setg[te] X, +/-0.0), X, fneg(X) -> fabs - if ((CC == ISD::SETGE || CC == ISD::SETGT) && - N1 == N3 && N4.getOpcode() == ISD::FNEG && - N1 == N4.getOperand(0)) - return getNode(ISD::FABS, VT, N1); - - // select (setl[te] X, +/-0.0), fneg(X), X -> fabs - if ((CC == ISD::SETLT || CC == ISD::SETLE) && - N1 == N4 && N3.getOpcode() == ISD::FNEG && - N3.getOperand(0) == N4) - return getNode(ISD::FABS, VT, N4); - } - } - - // check to see if we're select_cc'ing a select_cc. - // this allows us to turn: - // select_cc set[eq,ne] (select_cc cc, lhs, rhs, 1, 0), 0, true, false -> - // select_cc cc, lhs, rhs, true, false - if ((N1C && N1C->isNullValue() && N2.getOpcode() == ISD::SELECT_CC) || - (N2C && N2C->isNullValue() && N1.getOpcode() == ISD::SELECT_CC) && - (CC == ISD::SETEQ || CC == ISD::SETNE)) { - SDOperand SCC = N1C ? N2 : N1; - ConstantSDNode *SCCT = dyn_cast(SCC.getOperand(2)); - ConstantSDNode *SCCF = dyn_cast(SCC.getOperand(3)); - if (SCCT && SCCF && SCCF->isNullValue() && SCCT->getValue() == 1ULL) { - if (CC == ISD::SETEQ) std::swap(N3, N4); - return getNode(ISD::SELECT_CC, N3.getValueType(), SCC.getOperand(0), - SCC.getOperand(1), N3, N4, SCC.getOperand(4)); - } - } - - // Check to see if we can perform the "gzip trick", transforming - // select_cc setlt X, 0, A, 0 -> and (sra X, size(X)-1), A - if (N2C && N2C->isNullValue() && N4C && N4C->isNullValue() && - MVT::isInteger(N1.getValueType()) && - MVT::isInteger(N3.getValueType()) && CC == ISD::SETLT) { - MVT::ValueType XType = N1.getValueType(); - MVT::ValueType AType = N3.getValueType(); - if (XType >= AType) { - // and (sra X, size(X)-1, A) -> "and (srl X, C2), A" iff A is a - // single-bit constant. FIXME: remove once the dag combiner - // exists. - if (N3C && ((N3C->getValue() & (N3C->getValue()-1)) == 0)) { - unsigned ShCtV = Log2_64(N3C->getValue()); - ShCtV = MVT::getSizeInBits(XType)-ShCtV-1; - SDOperand ShCt = getConstant(ShCtV, TLI.getShiftAmountTy()); - SDOperand Shift = getNode(ISD::SRL, XType, N1, ShCt); - if (XType > AType) - Shift = getNode(ISD::TRUNCATE, AType, Shift); - return getNode(ISD::AND, AType, Shift, N3); - } - SDOperand Shift = getNode(ISD::SRA, XType, N1, - getConstant(MVT::getSizeInBits(XType)-1, - TLI.getShiftAmountTy())); - if (XType > AType) - Shift = getNode(ISD::TRUNCATE, AType, Shift); - return getNode(ISD::AND, AType, Shift, N3); - } - } - - // Check to see if this is the equivalent of setcc - if (N4C && N4C->isNullValue() && N3C && (N3C->getValue() == 1ULL)) { - MVT::ValueType XType = N1.getValueType(); - if (TLI.isOperationLegal(ISD::SETCC, TLI.getSetCCResultTy())) { - SDOperand Res = getSetCC(TLI.getSetCCResultTy(), N1, N2, CC); - if (Res.getValueType() != VT) - Res = getNode(ISD::ZERO_EXTEND, VT, Res); - return Res; - } - - // seteq X, 0 -> srl (ctlz X, log2(size(X))) - if (N2C && N2C->isNullValue() && CC == ISD::SETEQ && - TLI.isOperationLegal(ISD::CTLZ, XType)) { - SDOperand Ctlz = getNode(ISD::CTLZ, XType, N1); - return getNode(ISD::SRL, XType, Ctlz, - getConstant(Log2_32(MVT::getSizeInBits(XType)), - TLI.getShiftAmountTy())); - } - // setgt X, 0 -> srl (and (-X, ~X), size(X)-1) - if (N2C && N2C->isNullValue() && CC == ISD::SETGT) { - SDOperand NegN1 = getNode(ISD::SUB, XType, getConstant(0, XType), N1); - SDOperand NotN1 = getNode(ISD::XOR, XType, N1, getConstant(~0ULL, XType)); - return getNode(ISD::SRL, XType, getNode(ISD::AND, XType, NegN1, NotN1), - getConstant(MVT::getSizeInBits(XType)-1, - TLI.getShiftAmountTy())); - } - // setgt X, -1 -> xor (srl (X, size(X)-1), 1) - if (N2C && N2C->isAllOnesValue() && CC == ISD::SETGT) { - SDOperand Sign = getNode(ISD::SRL, XType, N1, - getConstant(MVT::getSizeInBits(XType)-1, - TLI.getShiftAmountTy())); - return getNode(ISD::XOR, XType, Sign, getConstant(1, XType)); - } - } - - // Check to see if this is an integer abs. select_cc setl[te] X, 0, -X, X -> - // Y = sra (X, size(X)-1); xor (add (X, Y), Y) - if (N2C && N2C->isNullValue() && (CC == ISD::SETLT || CC == ISD::SETLE) && - N1 == N4 && N3.getOpcode() == ISD::SUB && N1 == N3.getOperand(1)) { - if (ConstantSDNode *SubC = dyn_cast(N3.getOperand(0))) { - MVT::ValueType XType = N1.getValueType(); - if (SubC->isNullValue() && MVT::isInteger(XType)) { - SDOperand Shift = getNode(ISD::SRA, XType, N1, - getConstant(MVT::getSizeInBits(XType)-1, - TLI.getShiftAmountTy())); - return getNode(ISD::XOR, XType, getNode(ISD::ADD, XType, N1, Shift), - Shift); - } - } - } - - // Could not fold it. - return SDOperand(); -} - /// getNode - Gets or creates the specified node. /// SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT) { @@ -1370,9 +1242,6 @@ "True and False arms of SelectCC must have same type!"); assert(Ops[2].getValueType() == VT && "select_cc node must be of same type as true and false value!"); - SDOperand Simp = SimplifySelectCC(Ops[0], Ops[1], Ops[2], Ops[3], - cast(Ops[4])->get()); - if (Simp.Val) return Simp; break; } case ISD::BR_CC: { From lattner at cs.uiuc.edu Thu Oct 13 01:05:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 01:05:25 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/lha.ll Message-ID: <200510130605.BAA09562@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: lha.ll updated: 1.1 -> 1.2 --- Log message: Nate implemented this :) --- Diffs of the changes: (+0 -2) lha.ll | 2 -- 1 files changed, 2 deletions(-) Index: llvm/test/Regression/CodeGen/PowerPC/lha.ll diff -u llvm/test/Regression/CodeGen/PowerPC/lha.ll:1.1 llvm/test/Regression/CodeGen/PowerPC/lha.ll:1.2 --- llvm/test/Regression/CodeGen/PowerPC/lha.ll:1.1 Wed Aug 17 22:11:44 2005 +++ llvm/test/Regression/CodeGen/PowerPC/lha.ll Thu Oct 13 01:04:34 2005 @@ -1,8 +1,6 @@ ; RUN: llvm-as < %s | llc -march=ppc32 | grep lha -; XFAIL: * uint %test(short* %a) { -entry: %tmp.1 = load short* %a %tmp.2 = cast short %tmp.1 to uint ret uint %tmp.2 From lattner at cs.uiuc.edu Thu Oct 13 11:34:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 11:34:42 -0500 Subject: [llvm-commits] CVS: llvm/utils/profile.pl Message-ID: <200510131634.LAA16022@zion.cs.uiuc.edu> Changes in directory llvm/utils: profile.pl updated: 1.7 -> 1.8 --- Log message: apparently one of the makefile changes changed libprofile.so to profile.so --- Diffs of the changes: (+1 -1) profile.pl | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/profile.pl diff -u llvm/utils/profile.pl:1.7 llvm/utils/profile.pl:1.8 --- llvm/utils/profile.pl:1.7 Fri Jan 14 10:32:39 2005 +++ llvm/utils/profile.pl Thu Oct 13 11:34:24 2005 @@ -66,7 +66,7 @@ $LLIPath = `dirname $LLIPath`; chomp $LLIPath; -my $LibProfPath = $LLIPath . "/../../Debug/lib/libprofile_rt.so"; +my $LibProfPath = $LLIPath . "/../../Debug/lib/profile_rt.so"; system "opt -q -f $ProfilePass $BytecodeFile -o $BytecodeFile.inst"; system "lli -fake-argv0 '$BytecodeFile' -load $LibProfPath " . From pmeredit at cs.uiuc.edu Thu Oct 13 11:27:01 2005 From: pmeredit at cs.uiuc.edu (Patrick Meredith) Date: Thu, 13 Oct 2005 11:27:01 -0500 Subject: [llvm-commits] CVS: llvm/utils/DSAclean.py Message-ID: <200510131627.LAA15762@zion.cs.uiuc.edu> Changes in directory llvm/utils: DSAclean.py added (r1.1) --- Log message: This script is used to remove nodes with the label %tmp(.#)* and all edges associated with said node from the dot files produced by DSA. --- Diffs of the changes: (+30 -0) DSAclean.py | 30 ++++++++++++++++++++++++++++++ 1 files changed, 30 insertions(+) Index: llvm/utils/DSAclean.py diff -c /dev/null llvm/utils/DSAclean.py:1.1 *** /dev/null Thu Oct 13 11:27:00 2005 --- llvm/utils/DSAclean.py Thu Oct 13 11:26:50 2005 *************** *** 0 **** --- 1,30 ---- + #! /usr/bin/python + + #changelog: + #10/13/2005: exntended to remove variables of the form %tmp(.#)* rather than just + #%tmp.#, i.e. it now will remove %tmp.12.3.15 etc, additionally fixed a spelling error in + #the comments + #10/12/2005: now it only removes nodes and edges for which the label is %tmp.# rather + #than removing all lines for which the lable CONTAINS %tmp.# + import re + import sys + if( len(sys.argv) < 3 ): + print 'usage is: ./DSAclean ' + sys.exit(1) + #get a file object + input = open(sys.argv[1], 'r') + output = open(sys.argv[2], 'w') + #we'll get this one line at a time...while we could just put the whole thing in a string + #it would kill old computers + buffer = input.readline() + while buffer != '': + if re.compile("label(\s*)=(\s*)\"\s%tmp(.\d*)*(\s*)\"").search(buffer): + #skip next line, write neither this line nor the next + buffer = input.readline() + else: + #this isn't a tmp Node, we can write it + output.write(buffer) + #prepare for the next iteration + buffer = input.readline() + input.close() + output.close() From jlaskey at apple.com Thu Oct 13 11:44:11 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 13 Oct 2005 11:44:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200510131644.LAA26272@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.36 -> 1.37 --- Log message: Inhibit instructions from being pushed before function calls. This will minimize unnecessary spilling. --- Diffs of the changes: (+55 -3) ScheduleDAG.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 55 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.36 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.37 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.36 Wed Oct 12 13:29:35 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Thu Oct 13 11:44:00 2005 @@ -232,6 +232,7 @@ SDNode *Node; // DAG node unsigned Latency; // Cycles to complete instruction unsigned ResourceSet; // Bit vector of usable resources + bool IsCall; // Is function call unsigned Slot; // Node's time slot NodeGroup *Group; // Grouping information unsigned VRBase; // Virtual register base @@ -245,9 +246,13 @@ , Node(N) , Latency(0) , ResourceSet(0) + , IsCall(false) , Slot(0) , Group(NULL) , VRBase(0) +#ifndef NDEBUG + , Preorder(0) +#endif {} // Accessors @@ -375,6 +380,7 @@ RSInteger = 0x3, // Two integer units RSFloat = 0xC, // Two float units RSLoadStore = 0x30, // Two load store units + RSBranch = 0x400, // One branch unit RSOther = 0 // Processing unit independent }; @@ -663,12 +669,22 @@ /// GatherSchedulingInfo - Get latency and resource information about each node. /// void SimpleSched::GatherSchedulingInfo() { + // Track if groups are present + bool AreGroups = false; + + // For each node for (unsigned i = 0, N = NodeCount; i < N; i++) { + // Get node info NodeInfo* NI = &Info[i]; SDNode *Node = NI->Node; + + // Test for groups + if (NI->isInGroup()) AreGroups = true; + // FIXME: Pretend by using value type to choose metrics MVT::ValueType VT = Node->getValueType(0); + // If machine opcode if (Node->isTargetOpcode()) { MachineOpCode TOpc = Node->getTargetOpcode(); // FIXME: This is an ugly (but temporary!) hack to test the scheduler @@ -676,8 +692,9 @@ // FIXME NI->Latency = std::max(1, TII.maxLatency(TOpc)); // FIXME NI->ResourceSet = TII.resources(TOpc); if (TII.isCall(TOpc)) { - NI->ResourceSet = RSInteger; + NI->ResourceSet = RSBranch; NI->Latency = 40; + NI->IsCall = true; } else if (TII.isLoad(TOpc)) { NI->ResourceSet = RSLoadStore; NI->Latency = 5; @@ -713,6 +730,41 @@ // Sum up all the latencies for max tally size NSlots += NI->Latency; } + + // Unify metrics if in a group + if (AreGroups) { + for (unsigned i = 0, N = NodeCount; i < N; i++) { + NodeInfo* NI = &Info[i]; + + if (NI->isGroupLeader()) { + NodeGroup *Group = NI->Group; + unsigned Latency = 0; + unsigned MaxLat = 0; + unsigned ResourceSet = 0; + bool IsCall = false; + + for (NIIterator NGI = Group->begin(), NGE = Group->end(); + NGI != NGE; NGI++) { + NodeInfo* NGNI = *NGI; + Latency += NGNI->Latency; + IsCall = IsCall || NGNI->IsCall; + + if (MaxLat < NGNI->Latency) { + MaxLat = NGNI->Latency; + ResourceSet = NGNI->ResourceSet; + } + + NGNI->Latency = 0; + NGNI->ResourceSet = 0; + NGNI->IsCall = false; + } + + NI->Latency = Latency; + NI->ResourceSet = ResourceSet; + NI->IsCall = IsCall; + } + } + } } /// PrepareNodeInfo - Set up the basic minimum node info for scheduling. @@ -837,7 +889,7 @@ if (isStrongDependency(Other, NI)) { Slot = Other->Slot + Other->Latency; break; - } else if (isWeakDependency(Other, NI)) { + } else if (Other->IsCall || isWeakDependency(Other, NI)) { Slot = Other->Slot; break; } @@ -1134,7 +1186,7 @@ NodeGroup *Group = NI->Group; for (NIIterator NII = Group->begin(), E = Group->end(); NII != E; NII++) { - std::cerr << " "; + std::cerr << " "; printSI(std::cerr, *NII); std::cerr << "\n"; } From natebegeman at mac.com Thu Oct 13 12:15:49 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 13 Oct 2005 12:15:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200510131715.MAA08812@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.195 -> 1.196 --- Log message: Add support to Legalize for expanding i64 sextload/zextload into hi and lo parts. This should fix the crafty and signed long long unit test failure on x86 last night. --- Diffs of the changes: (+35 -0) LegalizeDAG.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.195 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.196 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.195 Wed Oct 12 22:11:28 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Oct 13 12:15:37 2005 @@ -3101,6 +3101,41 @@ Hi = LegalizeOp(Hi); break; } + case ISD::SEXTLOAD: { + SDOperand Chain = LegalizeOp(Node->getOperand(0)); + SDOperand Ptr = LegalizeOp(Node->getOperand(1)); + MVT::ValueType EVT = cast(Node->getOperand(3))->getVT(); + + if (EVT == NVT) + Lo = DAG.getLoad(NVT, Chain, Ptr, Node->getOperand(2)); + else + Lo = DAG.getExtLoad(ISD::SEXTLOAD, NVT, Chain, Ptr, Node->getOperand(2), + EVT); + // The high part is obtained by SRA'ing all but one of the bits of the lo + // part. + unsigned LoSize = MVT::getSizeInBits(Lo.getValueType()); + Hi = DAG.getNode(ISD::SRA, NVT, Lo, DAG.getConstant(LoSize-1, + TLI.getShiftAmountTy())); + Lo = LegalizeOp(Lo); + Hi = LegalizeOp(Hi); + break; + } + case ISD::ZEXTLOAD: { + SDOperand Chain = LegalizeOp(Node->getOperand(0)); + SDOperand Ptr = LegalizeOp(Node->getOperand(1)); + MVT::ValueType EVT = cast(Node->getOperand(3))->getVT(); + + if (EVT == NVT) + Lo = DAG.getLoad(NVT, Chain, Ptr, Node->getOperand(2)); + else + Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Chain, Ptr, Node->getOperand(2), + EVT); + // The high part is just a zero. + Hi = DAG.getConstant(0, NVT); + Lo = LegalizeOp(Lo); + Hi = LegalizeOp(Hi); + break; + } case ISD::ANY_EXTEND: { SDOperand In; switch (getTypeAction(Node->getOperand(0).getValueType())) { From pmeredit at cs.uiuc.edu Thu Oct 13 12:31:41 2005 From: pmeredit at cs.uiuc.edu (Patrick Meredith) Date: Thu, 13 Oct 2005 12:31:41 -0500 Subject: [llvm-commits] CVS: llvm/utils/DSAclean.py Message-ID: <200510131731.MAA22095@zion.cs.uiuc.edu> Changes in directory llvm/utils: DSAclean.py updated: 1.1 -> 1.2 --- Log message: Updated to be less restrictive on what is matched --- Diffs of the changes: (+3 -1) DSAclean.py | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/utils/DSAclean.py diff -u llvm/utils/DSAclean.py:1.1 llvm/utils/DSAclean.py:1.2 --- llvm/utils/DSAclean.py:1.1 Thu Oct 13 11:26:50 2005 +++ llvm/utils/DSAclean.py Thu Oct 13 12:31:30 2005 @@ -1,6 +1,8 @@ #! /usr/bin/python #changelog: +#10/13/2005b: replaced the # in tmp(.#*)* with alphanumeric and _, this will then remove +#nodes such as %tmp.1.i and %tmp._i.3 #10/13/2005: exntended to remove variables of the form %tmp(.#)* rather than just #%tmp.#, i.e. it now will remove %tmp.12.3.15 etc, additionally fixed a spelling error in #the comments @@ -18,7 +20,7 @@ #it would kill old computers buffer = input.readline() while buffer != '': - if re.compile("label(\s*)=(\s*)\"\s%tmp(.\d*)*(\s*)\"").search(buffer): + if re.compile("label(\s*)=(\s*)\"\s%tmp(.\w*)*(\s*)\"").search(buffer): #skip next line, write neither this line nor the next buffer = input.readline() else: From lattner at cs.uiuc.edu Thu Oct 13 13:16:45 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 13:16:45 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510131816.NAA23975@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.35 -> 1.36 --- Log message: Fix a minor bug in the dag combiner that broke pcompress2 and some other tests. --- Diffs of the changes: (+3 -4) DAGCombiner.cpp | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.35 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.36 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.35 Wed Oct 12 22:11:28 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Oct 13 13:16:34 2005 @@ -805,13 +805,12 @@ // before Legalize, or the resulting zextload is legal on the target, then // go ahead and do the fold. if ((N1C->getValue() == (1ULL << MVT::getSizeInBits(EVT))-1) && - (!AfterLegalize || - TargetLowering::Legal == TLI.getOperationAction(ISD::ZEXTLOAD, EVT))) { + (!AfterLegalize || TLI.isOperationLegal(ISD::ZEXTLOAD, EVT))) { SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), EVT); - CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); WorkList.push_back(N); + CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1)); return SDOperand(); } } @@ -827,8 +826,8 @@ SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), EVT); - CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); WorkList.push_back(N); + CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1)); return SDOperand(); } } From natebegeman at mac.com Thu Oct 13 13:35:10 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 13 Oct 2005 13:35:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510131835.NAA24127@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.36 -> 1.37 --- Log message: Fix the remaining DAGCombiner issues pointed out by sabre. This should fix the remainder of the failures introduced by my patch last night. --- Diffs of the changes: (+11 -16) DAGCombiner.cpp | 27 +++++++++++---------------- 1 files changed, 11 insertions(+), 16 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.36 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.37 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.36 Thu Oct 13 13:16:34 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Oct 13 13:34:58 2005 @@ -801,10 +801,9 @@ // fold (zext_inreg (extload x)) -> (zextload x) if (N1C && N0.getOpcode() == ISD::EXTLOAD) { MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); - // If the type of the zext_inreg and the extload match, and we're running - // before Legalize, or the resulting zextload is legal on the target, then - // go ahead and do the fold. - if ((N1C->getValue() == (1ULL << MVT::getSizeInBits(EVT))-1) && + // If we zero all the possible extended bits, then we can turn this into + // a zextload if we are running before legalize or the operation is legal. + if (MaskedValueIsZero(SDOperand(N,0), ~0ULL< (zextload x) iff load has one use if (N1C && N0.getOpcode() == ISD::SEXTLOAD && N0.Val->hasNUsesOfValue(1, 0)) { MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); - // If the type of the zext_inreg and the extload match, and we're running - // before Legalize, or the resulting zextload is legal on the target, then - // go ahead and do the fold. - if ((N1C->getValue() == (1ULL << MVT::getSizeInBits(EVT))-1) && - (!AfterLegalize || - TargetLowering::Legal == TLI.getOperationAction(ISD::ZEXTLOAD, EVT))) { + // If we zero all the possible extended bits, then we can turn this into + // a zextload if we are running before legalize or the operation is legal. + if (MaskedValueIsZero(SDOperand(N,0), ~0ULL< (sextload x) if (N0.getOpcode() == ISD::EXTLOAD && EVT == cast(N0.getOperand(3))->getVT() && - (!AfterLegalize || - (TargetLowering::Legal == TLI.getOperationAction(ISD::SEXTLOAD, EVT)))) { + (!AfterLegalize || TLI.isOperationLegal(ISD::SEXTLOAD, EVT))) { SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), EVT); - CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); WorkList.push_back(N); + CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1)); return SDOperand(); } // fold (sext_inreg (zextload x)) -> (sextload x) iff load has one use if (N0.getOpcode() == ISD::ZEXTLOAD && N0.Val->hasNUsesOfValue(1, 0) && EVT == cast(N0.getOperand(3))->getVT() && - (!AfterLegalize || - (TargetLowering::Legal == TLI.getOperationAction(ISD::SEXTLOAD, EVT)))) { + (!AfterLegalize || TLI.isOperationLegal(ISD::SEXTLOAD, EVT))) { SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), EVT); - CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); WorkList.push_back(N); + CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1)); return SDOperand(); } return SDOperand(); From lattner at cs.uiuc.edu Thu Oct 13 15:07:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 15:07:53 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200510132007.PAA24917@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.196 -> 1.197 --- Log message: Implement PromoteOp for *EXTLOAD, allowing MallocBench/gs to Legalize --- Diffs of the changes: (+10 -0) LegalizeDAG.cpp | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.196 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.197 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.196 Thu Oct 13 12:15:37 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Oct 13 15:07:41 2005 @@ -2350,6 +2350,16 @@ // Remember that we legalized the chain. AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); break; + case ISD::SEXTLOAD: + case ISD::ZEXTLOAD: + case ISD::EXTLOAD: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. + Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2, + Node->getOperand(2), Node->getOperand(3)); + // Remember that we legalized the chain. + AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); + break; case ISD::SELECT: switch (getTypeAction(Node->getOperand(0).getValueType())) { case Expand: assert(0 && "It's impossible to expand bools"); From lattner at cs.uiuc.edu Thu Oct 13 16:44:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 16:44:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200510132144.QAA26006@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.197 -> 1.198 --- Log message: When ExpandOp'ing a [SZ]EXTLOAD, make sure to remember that the chain is also legal. Add support for ExpandOp'ing raw EXTLOADs too. --- Diffs of the changes: (+28 -2) LegalizeDAG.cpp | 30 ++++++++++++++++++++++++++++-- 1 files changed, 28 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.197 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.198 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.197 Thu Oct 13 15:07:41 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Oct 13 16:44:47 2005 @@ -3121,6 +3121,10 @@ else Lo = DAG.getExtLoad(ISD::SEXTLOAD, NVT, Chain, Ptr, Node->getOperand(2), EVT); + + // Remember that we legalized the chain. + AddLegalizedOperand(SDOperand(Node, 1), Lo.getValue(1)); + // The high part is obtained by SRA'ing all but one of the bits of the lo // part. unsigned LoSize = MVT::getSizeInBits(Lo.getValueType()); @@ -3140,10 +3144,32 @@ else Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Chain, Ptr, Node->getOperand(2), EVT); + + // Remember that we legalized the chain. + AddLegalizedOperand(SDOperand(Node, 1), Lo.getValue(1)); + // The high part is just a zero. - Hi = DAG.getConstant(0, NVT); + Hi = LegalizeOp(DAG.getConstant(0, NVT)); + Lo = LegalizeOp(Lo); + break; + } + case ISD::EXTLOAD: { + SDOperand Chain = LegalizeOp(Node->getOperand(0)); + SDOperand Ptr = LegalizeOp(Node->getOperand(1)); + MVT::ValueType EVT = cast(Node->getOperand(3))->getVT(); + + if (EVT == NVT) + Lo = DAG.getLoad(NVT, Chain, Ptr, Node->getOperand(2)); + else + Lo = DAG.getExtLoad(ISD::EXTLOAD, NVT, Chain, Ptr, Node->getOperand(2), + EVT); + + // Remember that we legalized the chain. + AddLegalizedOperand(SDOperand(Node, 1), Lo.getValue(1)); + + // The high part is undefined. + Hi = LegalizeOp(DAG.getNode(ISD::UNDEF, NVT)); Lo = LegalizeOp(Lo); - Hi = LegalizeOp(Hi); break; } case ISD::ANY_EXTEND: { From lattner at cs.uiuc.edu Thu Oct 13 16:52:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 16:52:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510132152.QAA26085@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.37 -> 1.38 --- Log message: Fix some bugs in (sext (load x)) --- Diffs of the changes: (+2 -1) DAGCombiner.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.37 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.38 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.37 Thu Oct 13 13:34:58 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Oct 13 16:52:31 2005 @@ -1248,8 +1248,9 @@ SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), N0.getValueType()); - CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); WorkList.push_back(N); + CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), + ExtLoad.getValue(1)); return SDOperand(); } return SDOperand(); From lattner at cs.uiuc.edu Thu Oct 13 17:10:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 17:10:16 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510132210.RAA26234@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.38 -> 1.39 --- Log message: Fix the trunc(load) case, finally allowing crafty and povray to pass --- Diffs of the changes: (+2 -1) DAGCombiner.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.38 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.39 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.38 Thu Oct 13 16:52:31 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Oct 13 17:10:05 2005 @@ -462,6 +462,7 @@ if (N->getOperand(1).getOpcode() == ISD::EntryToken) return N->getOperand(0); } + // fold (tokenfactor (tokenfactor)) -> tokenfactor for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { SDOperand Op = N->getOperand(i); @@ -1386,8 +1387,8 @@ DAG.getConstant(PtrOff, PtrType)); WorkList.push_back(NewPtr.Val); SDOperand Load = DAG.getLoad(VT, N0.getOperand(0), NewPtr,N0.getOperand(2)); - CombineTo(N0.Val, Load, Load.getOperand(0)); WorkList.push_back(N); + CombineTo(N0.Val, Load, Load.getValue(1)); return SDOperand(); } return SDOperand(); From lattner at cs.uiuc.edu Thu Oct 13 19:33:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 19:33:17 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/CommandLine.h Message-ID: <200510140033.TAA09181@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: CommandLine.h updated: 1.48 -> 1.49 --- Log message: Fix errors when compiling with -pedantic --- Diffs of the changes: (+5 -5) CommandLine.h | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/include/llvm/Support/CommandLine.h diff -u llvm/include/llvm/Support/CommandLine.h:1.48 llvm/include/llvm/Support/CommandLine.h:1.49 --- llvm/include/llvm/Support/CommandLine.h:1.48 Fri Aug 26 04:24:46 2005 +++ llvm/include/llvm/Support/CommandLine.h Thu Oct 13 19:33:05 2005 @@ -66,21 +66,21 @@ // ConsumeAfter = 0x05, - OccurrencesMask = 0x07, + OccurrencesMask = 0x07 }; enum ValueExpected { // Is a value required for the option? ValueOptional = 0x08, // The value can appear... or not ValueRequired = 0x10, // The value is required to appear! ValueDisallowed = 0x18, // A value may not be specified (for flags) - ValueMask = 0x18, + ValueMask = 0x18 }; enum OptionHidden { // Control whether -help shows this option NotHidden = 0x20, // Option included in --help & --help-hidden Hidden = 0x40, // -help doesn't, but --help-hidden does ReallyHidden = 0x60, // Neither --help nor --help-hidden show this arg - HiddenMask = 0x60, + HiddenMask = 0x60 }; // Formatting flags - This controls special features that the option might have @@ -103,13 +103,13 @@ Positional = 0x080, // Is a positional argument, no '-' required Prefix = 0x100, // Can this option directly prefix its value? Grouping = 0x180, // Can this option group with other options? - FormattingMask = 0x180, // Union of the above flags. + FormattingMask = 0x180 // Union of the above flags. }; enum MiscFlags { // Miscellaneous flags to adjust argument CommaSeparated = 0x200, // Should this cl::list split between commas? PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args? - MiscMask = 0x600, // Union of the above flags. + MiscMask = 0x600 // Union of the above flags. }; From natebegeman at mac.com Thu Oct 13 20:12:32 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 13 Oct 2005 20:12:32 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp LegalizeDAG.cpp Message-ID: <200510140112.UAA09308@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.39 -> 1.40 LegalizeDAG.cpp updated: 1.198 -> 1.199 --- Log message: Relax the checking on zextload generation a bit, since as sabre pointed out you could be AND'ing with the result of a shift that shifts out all the bits you care about, in addition to a constant. Also, move over an add/sub_parts fold from legalize to the dag combiner, where it works for things other than constants. Woot! --- Diffs of the changes: (+49 -27) DAGCombiner.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----- LegalizeDAG.cpp | 22 ---------------------- 2 files changed, 49 insertions(+), 27 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.39 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.40 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.39 Thu Oct 13 17:10:05 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Oct 13 20:12:21 2005 @@ -147,11 +147,13 @@ SDOperand visitSELECT(SDNode *N); SDOperand visitSELECT_CC(SDNode *N); SDOperand visitSETCC(SDNode *N); + SDOperand visitADD_PARTS(SDNode *N); + SDOperand visitSUB_PARTS(SDNode *N); SDOperand visitSIGN_EXTEND(SDNode *N); SDOperand visitZERO_EXTEND(SDNode *N); SDOperand visitSIGN_EXTEND_INREG(SDNode *N); SDOperand visitTRUNCATE(SDNode *N); - + SDOperand visitFADD(SDNode *N); SDOperand visitFSUB(SDNode *N); SDOperand visitFMUL(SDNode *N); @@ -422,6 +424,8 @@ case ISD::SELECT: return visitSELECT(N); case ISD::SELECT_CC: return visitSELECT_CC(N); case ISD::SETCC: return visitSETCC(N); + case ISD::ADD_PARTS: return visitADD_PARTS(N); + case ISD::SUB_PARTS: return visitSUB_PARTS(N); case ISD::SIGN_EXTEND: return visitSIGN_EXTEND(N); case ISD::ZERO_EXTEND: return visitZERO_EXTEND(N); case ISD::SIGN_EXTEND_INREG: return visitSIGN_EXTEND_INREG(N); @@ -800,11 +804,11 @@ return DAG.getNode(N0.getOpcode(), VT, ANDNode, N0.getOperand(1)); } // fold (zext_inreg (extload x)) -> (zextload x) - if (N1C && N0.getOpcode() == ISD::EXTLOAD) { + if (N0.getOpcode() == ISD::EXTLOAD) { MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); // If we zero all the possible extended bits, then we can turn this into // a zextload if we are running before legalize or the operation is legal. - if (MaskedValueIsZero(SDOperand(N,0), ~0ULL< (zextload x) iff load has one use - if (N1C && N0.getOpcode() == ISD::SEXTLOAD && N0.Val->hasNUsesOfValue(1, 0)) { + if (N0.getOpcode() == ISD::SEXTLOAD && N0.Val->hasNUsesOfValue(1, 0)) { MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); // If we zero all the possible extended bits, then we can turn this into // a zextload if we are running before legalize or the operation is legal. - if (MaskedValueIsZero(SDOperand(N,0), ~0ULL<(N->getOperand(2))->get()); } +SDOperand DAGCombiner::visitADD_PARTS(SDNode *N) { + SDOperand LHSLo = N->getOperand(0); + SDOperand RHSLo = N->getOperand(2); + MVT::ValueType VT = LHSLo.getValueType(); + + // fold (a_Hi, 0) + (b_Hi, b_Lo) -> (b_Hi + a_Hi, b_Lo) + if (MaskedValueIsZero(LHSLo, (1ULL << MVT::getSizeInBits(VT))-1, TLI)) { + SDOperand Hi = DAG.getNode(ISD::ADD, VT, N->getOperand(1), + N->getOperand(3)); + WorkList.push_back(Hi.Val); + CombineTo(N, RHSLo, Hi); + return SDOperand(); + } + // fold (a_Hi, a_Lo) + (b_Hi, 0) -> (a_Hi + b_Hi, a_Lo) + if (MaskedValueIsZero(RHSLo, (1ULL << MVT::getSizeInBits(VT))-1, TLI)) { + SDOperand Hi = DAG.getNode(ISD::ADD, VT, N->getOperand(1), + N->getOperand(3)); + WorkList.push_back(Hi.Val); + CombineTo(N, LHSLo, Hi); + return SDOperand(); + } + return SDOperand(); +} + +SDOperand DAGCombiner::visitSUB_PARTS(SDNode *N) { + SDOperand LHSLo = N->getOperand(0); + SDOperand RHSLo = N->getOperand(2); + MVT::ValueType VT = LHSLo.getValueType(); + + // fold (a_Hi, a_Lo) - (b_Hi, 0) -> (a_Hi - b_Hi, a_Lo) + if (MaskedValueIsZero(RHSLo, (1ULL << MVT::getSizeInBits(VT))-1, TLI)) { + SDOperand Hi = DAG.getNode(ISD::SUB, VT, N->getOperand(1), + N->getOperand(3)); + WorkList.push_back(Hi.Val); + CombineTo(N, LHSLo, Hi); + return SDOperand(); + } + return SDOperand(); +} + SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) { SDOperand N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast(N0); Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.198 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.199 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.198 Thu Oct 13 16:44:47 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Oct 13 20:12:21 2005 @@ -2449,33 +2449,11 @@ ExpandOp(LHS, LHSL, LHSH); ExpandOp(RHS, RHSL, RHSH); - // FIXME: this should be moved to the dag combiner someday. - assert(NodeOp == ISD::ADD_PARTS || NodeOp == ISD::SUB_PARTS); - if (LHSL.getValueType() == MVT::i32) { - SDOperand LowEl = SDOperand(0,0); - if (ConstantSDNode *C = dyn_cast(LHSL)) - if (C->getValue() == 0) - LowEl = RHSL; - if (ConstantSDNode *C = dyn_cast(RHSL)) - if (C->getValue() == 0) - LowEl = LHSL; - if (LowEl.Val) { - // Turn this into an add/sub of the high part only. - SDOperand HiEl = - DAG.getNode(NodeOp == ISD::ADD_PARTS ? ISD::ADD : ISD::SUB, - LowEl.getValueType(), LHSH, RHSH); - Lo = LowEl; - Hi = HiEl; - return; - } - } - std::vector Ops; Ops.push_back(LHSL); Ops.push_back(LHSH); Ops.push_back(RHSL); Ops.push_back(RHSH); - std::vector VTs(2, LHSL.getValueType()); Lo = DAG.getNode(NodeOp, VTs, Ops); Hi = Lo.getValue(1); From lattner at cs.uiuc.edu Thu Oct 13 20:28:46 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 20:28:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Mangler.cpp Message-ID: <200510140128.UAA16729@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Mangler.cpp updated: 1.18 -> 1.19 --- Log message: Allow $ --- Diffs of the changes: (+1 -1) Mangler.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/VMCore/Mangler.cpp diff -u llvm/lib/VMCore/Mangler.cpp:1.18 llvm/lib/VMCore/Mangler.cpp:1.19 --- llvm/lib/VMCore/Mangler.cpp:1.18 Sat Sep 24 03:24:28 2005 +++ llvm/lib/VMCore/Mangler.cpp Thu Oct 13 20:28:34 2005 @@ -44,7 +44,7 @@ for (std::string::const_iterator E = X.end(); I != E; ++I) if ((*I < 'a' || *I > 'z') && (*I < 'A' || *I > 'Z') && - (*I < '0' || *I > '9') && *I != '_') + (*I < '0' || *I > '9') && *I != '_' && *I != '$') Result += MangleLetter(*I); else Result += *I; From natebegeman at mac.com Thu Oct 13 20:29:19 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 13 Oct 2005 20:29:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510140129.UAA19467@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.40 -> 1.41 --- Log message: fold sext_in_reg, sext_in_reg where both have the same VT. This was popping up in Fourinarow. --- Diffs of the changes: (+1 -1) DAGCombiner.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.40 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.41 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.40 Thu Oct 13 20:12:21 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Oct 13 20:29:07 2005 @@ -1330,7 +1330,7 @@ } // fold (sext_in_reg (sext_in_reg x, VT2), VT1) -> (sext_in_reg x, minVT) pt1 if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG && - cast(N0.getOperand(1))->getVT() < EVT) { + cast(N0.getOperand(1))->getVT() <= EVT) { return N0; } // fold (sext_in_reg (sext_in_reg x, VT2), VT1) -> (sext_in_reg x, minVT) pt2 From lattner at cs.uiuc.edu Thu Oct 13 22:55:01 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 22:55:01 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenTarget.cpp Message-ID: <200510140355.WAA02447@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenTarget.cpp updated: 1.39 -> 1.40 --- Log message: Do not let getLegalValueTypes return a list with duplicates in it --- Diffs of the changes: (+7 -0) CodeGenTarget.cpp | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/utils/TableGen/CodeGenTarget.cpp diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.39 llvm/utils/TableGen/CodeGenTarget.cpp:1.40 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.39 Wed Sep 14 16:13:50 2005 +++ llvm/utils/TableGen/CodeGenTarget.cpp Thu Oct 13 22:54:49 2005 @@ -19,6 +19,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" #include +#include using namespace llvm; static cl::opt @@ -179,6 +180,12 @@ const std::vector &RCs = getRegisterClasses(); for (unsigned i = 0, e = RCs.size(); i != e; ++i) LegalValueTypes.push_back(RCs[i].VT); + + // Remove duplicates. + std::sort(LegalValueTypes.begin(), LegalValueTypes.end()); + LegalValueTypes.erase(std::unique(LegalValueTypes.begin(), + LegalValueTypes.end()), + LegalValueTypes.end()); } From lattner at cs.uiuc.edu Thu Oct 13 23:11:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 23:11:25 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200510140411.XAA04040@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.51 -> 1.52 DAGISelEmitter.h updated: 1.29 -> 1.30 --- Log message: Implement a couple of new (important) features. 1. If an operation has to be int or fp and the target only supports one int or fp type, relize that the op has to have that type. 2. If a target has operations on multiple types, do not emit matching code for patterns involving those operators, since we do not emit the code to check for them yet. This prevents PPC from generating FP ops currently. Also move some code around into more logical places. --- Diffs of the changes: (+128 -50) DAGISelEmitter.cpp | 173 ++++++++++++++++++++++++++++++++++++++--------------- DAGISelEmitter.h | 5 - 2 files changed, 128 insertions(+), 50 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.51 llvm/utils/TableGen/DAGISelEmitter.cpp:1.52 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.51 Thu Sep 29 17:36:54 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Oct 13 23:11:13 2005 @@ -75,6 +75,8 @@ TP.error(N->getOperator()->getName() + " node requires exactly " + itostr(NodeInfo.getNumOperands()) + " operands!"); } + + const CodeGenTarget &CGT = TP.getDAGISelEmitter().getTargetInfo(); TreePatternNode *NodeToApply = getOperandNum(OperandNo, N, NumResults); @@ -83,18 +85,51 @@ case SDTCisVT: // Operand must be a particular type. return NodeToApply->UpdateNodeType(x.SDTCisVT_Info.VT, TP); - case SDTCisInt: + case SDTCisInt: { if (NodeToApply->hasTypeSet() && !MVT::isInteger(NodeToApply->getType())) NodeToApply->UpdateNodeType(MVT::i1, TP); // throw an error. - // FIXME: can tell from the target if there is only one Int type supported. + // If there is only one integer type supported, this must be it. + const std::vector &VTs = CGT.getLegalValueTypes(); + MVT::ValueType VT = MVT::LAST_VALUETYPE; + for (unsigned i = 0, e = VTs.size(); i != e; ++i) + if (MVT::isInteger(VTs[i])) { + if (VT == MVT::LAST_VALUETYPE) + VT = VTs[i]; // First integer type we've found. + else { + VT = MVT::LAST_VALUETYPE; + break; + } + } + + // If we found exactly one supported integer type, apply it. + if (VT != MVT::LAST_VALUETYPE) + return NodeToApply->UpdateNodeType(VT, TP); return false; - case SDTCisFP: + } + case SDTCisFP: { if (NodeToApply->hasTypeSet() && !MVT::isFloatingPoint(NodeToApply->getType())) NodeToApply->UpdateNodeType(MVT::f32, TP); // throw an error. - // FIXME: can tell from the target if there is only one FP type supported. + + // If there is only one FP type supported, this must be it. + const std::vector &VTs = CGT.getLegalValueTypes(); + MVT::ValueType VT = MVT::LAST_VALUETYPE; + for (unsigned i = 0, e = VTs.size(); i != e; ++i) + if (MVT::isFloatingPoint(VTs[i])) { + if (VT == MVT::LAST_VALUETYPE) + VT = VTs[i]; // First integer type we've found. + else { + VT = MVT::LAST_VALUETYPE; + break; + } + } + + // If we found exactly one supported FP type, apply it. + if (VT != MVT::LAST_VALUETYPE) + return NodeToApply->UpdateNodeType(VT, TP); return false; + } case SDTCisSameAs: { TreePatternNode *OtherNode = getOperandNum(x.SDTCisSameAs_Info.OtherOperandNum, N, NumResults); @@ -344,18 +379,51 @@ return FragTree; } +/// getIntrinsicType - Check to see if the specified record has an intrinsic +/// type which should be applied to it. This infer the type of register +/// references from the register file information, for example. +/// +static MVT::ValueType getIntrinsicType(Record *R, bool NotRegisters, TreePattern &TP) { + // Check to see if this is a register or a register class... + if (R->isSubClassOf("RegisterClass")) { + if (NotRegisters) return MVT::LAST_VALUETYPE; + return getValueType(R->getValueAsDef("RegType")); + } else if (R->isSubClassOf("PatFrag")) { + // Pattern fragment types will be resolved when they are inlined. + return MVT::LAST_VALUETYPE; + } else if (R->isSubClassOf("Register")) { + assert(0 && "Explicit registers not handled here yet!\n"); + return MVT::LAST_VALUETYPE; + } else if (R->isSubClassOf("ValueType")) { + // Using a VTSDNode. + return MVT::Other; + } else if (R->getName() == "node") { + // Placeholder. + return MVT::LAST_VALUETYPE; + } + + TP.error("Unknown node flavor used in pattern: " + R->getName()); + return MVT::Other; +} + /// ApplyTypeConstraints - Apply all of the type constraints relevent to /// this node and its children in the tree. This returns true if it makes a /// change, false otherwise. If a type contradiction is found, throw an /// exception. -bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP) { - if (isLeaf()) return false; +bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { + if (isLeaf()) { + if (DefInit *DI = dynamic_cast(getLeafValue())) + // If it's a regclass or something else known, include the type. + return UpdateNodeType(getIntrinsicType(DI->getDef(), NotRegisters, TP), + TP); + return false; + } // special handling for set, which isn't really an SDNode. if (getOperator()->getName() == "set") { assert (getNumChildren() == 2 && "Only handle 2 operand set's for now!"); - bool MadeChange = getChild(0)->ApplyTypeConstraints(TP); - MadeChange |= getChild(1)->ApplyTypeConstraints(TP); + bool MadeChange = getChild(0)->ApplyTypeConstraints(TP, NotRegisters); + MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters); // Types of operands must match. MadeChange |= getChild(0)->UpdateNodeType(getChild(1)->getType(), TP); @@ -367,7 +435,7 @@ bool MadeChange = NI.ApplyTypeConstraints(this, TP); for (unsigned i = 0, e = getNumChildren(); i != e; ++i) - MadeChange |= getChild(i)->ApplyTypeConstraints(TP); + MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); return MadeChange; } else if (getOperator()->isSubClassOf("Instruction")) { const DAGInstruction &Inst = @@ -383,7 +451,7 @@ utostr(getNumChildren()) + " operands!"); for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { MadeChange |= getChild(i)->UpdateNodeType(Inst.getOperandType(i), TP); - MadeChange |= getChild(i)->ApplyTypeConstraints(TP); + MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); } return MadeChange; } else { @@ -456,32 +524,6 @@ throw "In " + TheRecord->getName() + ": " + Msg; } -/// getIntrinsicType - Check to see if the specified record has an intrinsic -/// type which should be applied to it. This infer the type of register -/// references from the register file information, for example. -/// -MVT::ValueType TreePattern::getIntrinsicType(Record *R) const { - // Check to see if this is a register or a register class... - if (R->isSubClassOf("RegisterClass")) - return getValueType(R->getValueAsDef("RegType")); - else if (R->isSubClassOf("PatFrag")) { - // Pattern fragment types will be resolved when they are inlined. - return MVT::LAST_VALUETYPE; - } else if (R->isSubClassOf("Register")) { - assert(0 && "Explicit registers not handled here yet!\n"); - return MVT::LAST_VALUETYPE; - } else if (R->isSubClassOf("ValueType")) { - // Using a VTSDNode. - return MVT::Other; - } else if (R->getName() == "node") { - // Placeholder. - return MVT::LAST_VALUETYPE; - } - - error("Unknown node flavor used in pattern: " + R->getName()); - return MVT::Other; -} - TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) { Record *Operator = Dag->getNodeType(); @@ -489,7 +531,7 @@ // If the operator is a ValueType, then this must be "type cast" of a leaf // node. if (Dag->getNumArgs() != 1) - error("Type cast only valid for a leaf node!"); + error("Type cast only takes one operand!"); Init *Arg = Dag->getArg(0); TreePatternNode *New; @@ -504,8 +546,6 @@ } New = new TreePatternNode(DI); - // If it's a regclass or something else known, set the type. - New->setType(getIntrinsicType(DI->getDef())); } else if (DagInit *DI = dynamic_cast(Arg)) { New = ParseTreePattern(DI); } else { @@ -546,9 +586,6 @@ Node->setName(Dag->getArgName(i)); Children.push_back(Node); - // If it's a regclass or something else known, set the type. - Node->setType(getIntrinsicType(R)); - // Input argument? if (R->getName() == "node") { if (Dag->getArgName(i).empty()) @@ -573,7 +610,7 @@ while (MadeChange) { MadeChange = false; for (unsigned i = 0, e = Trees.size(); i != e; ++i) - MadeChange |= Trees[i]->ApplyTypeConstraints(*this); + MadeChange |= Trees[i]->ApplyTypeConstraints(*this, false); } bool HasUnresolvedTypes = false; @@ -1517,6 +1554,14 @@ } } +/// RemoveAllTypes - A quick recursive walk over a pattern which removes all +/// type information from it. +static void RemoveAllTypes(TreePatternNode *N) { + N->setType(MVT::LAST_VALUETYPE); + if (!N->isLeaf()) + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) + RemoveAllTypes(N->getChild(i)); +} /// 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 @@ -1537,12 +1582,44 @@ std::map VariableMap; EmitMatchForPattern(Pattern.first, "N", VariableMap, PatternNo, OS); - unsigned TmpNo = 0; - unsigned Res = CodeGenPatternResult(Pattern.second, TmpNo, VariableMap, OS); + // TP - Get *SOME* tree pattern, we don't care which. + TreePattern &TP = *PatternFragments.begin()->second; + + // At this point, we know that we structurally match the pattern, but the + // types of the nodes may not match. Figure out the fewest number of type + // comparisons we need to emit. For example, if there is only one integer + // type supported by a target, there should be no type comparisons at all for + // integer patterns! + // + // To figure out the fewest number of type checks needed, clone the pattern, + // remove the types, then perform type inference on the pattern as a whole. + // If there are unresolved types, emit an explicit check for those types, + // apply the type to the tree, then rerun type inference. Iterate until all + // types are resolved. + // + TreePatternNode *Pat = Pattern.first->clone(); + RemoveAllTypes(Pat); + bool MadeChange = true; + try { + while (MadeChange) + MadeChange = Pat->ApplyTypeConstraints(TP,true/*Ignore reg constraints*/); + } catch (...) { + assert(0 && "Error: could not find consistent types for something we" + " already decided was ok!"); + abort(); + } + + if (!Pat->ContainsUnresolvedType()) { + unsigned TmpNo = 0; + unsigned Res = CodeGenPatternResult(Pattern.second, TmpNo, VariableMap, OS); + + // Add the result to the map if it has multiple uses. + OS << " if (!N.Val->hasOneUse()) CodeGenMap[N] = Tmp" << Res << ";\n"; + OS << " return Tmp" << Res << ";\n"; + } + + delete Pat; - // Add the result to the map if it has multiple uses. - OS << " if (!N.Val->hasOneUse()) CodeGenMap[N] = Tmp" << Res << ";\n"; - OS << " return Tmp" << Res << ";\n"; OS << " }\n P" << PatternNo << "Fail:\n"; } Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.29 llvm/utils/TableGen/DAGISelEmitter.h:1.30 --- llvm/utils/TableGen/DAGISelEmitter.h:1.29 Thu Sep 29 14:28:10 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Thu Oct 13 23:11:13 2005 @@ -194,7 +194,7 @@ /// this node and its children in the tree. This returns true if it makes a /// change, false otherwise. If a type contradiction is found, throw an /// exception. - bool ApplyTypeConstraints(TreePattern &TP); + bool ApplyTypeConstraints(TreePattern &TP, bool NotRegisters); /// UpdateNodeType - Set the node type of N to VT if VT contains /// information. If N already contains a conflicting type, then throw an @@ -290,7 +290,6 @@ void dump() const; private: - MVT::ValueType getIntrinsicType(Record *R) const; TreePatternNode *ParseTreePattern(DagInit *DI); }; @@ -353,6 +352,8 @@ // run - Output the isel, returning true on failure. void run(std::ostream &OS); + const CodeGenTarget &getTargetInfo() const { return Target; } + const SDNodeInfo &getSDNodeInfo(Record *R) const { assert(SDNodes.count(R) && "Unknown node!"); return SDNodes.find(R)->second; From lattner at cs.uiuc.edu Thu Oct 13 23:54:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 23:54:04 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200510140454.XAA20457@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.52 -> 1.53 DAGISelEmitter.h updated: 1.30 -> 1.31 --- Log message: Add basic support for recognizing a new SDTCisOpSmallerThanOp type constraint --- Diffs of the changes: (+13 -1) DAGISelEmitter.cpp | 8 ++++++++ DAGISelEmitter.h | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.52 llvm/utils/TableGen/DAGISelEmitter.cpp:1.53 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.52 Thu Oct 13 23:11:13 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Oct 13 23:53:53 2005 @@ -40,6 +40,10 @@ ConstraintType = SDTCisVTSmallerThanOp; x.SDTCisVTSmallerThanOp_Info.OtherOperandNum = R->getValueAsInt("OtherOperandNum"); + } else if (R->isSubClassOf("SDTCisOpSmallerThanOp")) { + ConstraintType = SDTCisOpSmallerThanOp; + x.SDTCisOpSmallerThanOp_Info.BigOperandNum = + R->getValueAsInt("BigOperandNum"); } else { std::cerr << "Unrecognized SDTypeConstraint '" << R->getName() << "'!\n"; exit(1); @@ -157,6 +161,10 @@ OtherNode->UpdateNodeType(MVT::Other, TP); // Throw an error. return false; } + case SDTCisOpSmallerThanOp: { + // TODO + return false; + } } return false; } Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.30 llvm/utils/TableGen/DAGISelEmitter.h:1.31 --- llvm/utils/TableGen/DAGISelEmitter.h:1.30 Thu Oct 13 23:11:13 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Thu Oct 13 23:53:53 2005 @@ -34,7 +34,8 @@ unsigned OperandNo; // The operand # this constraint applies to. enum { - SDTCisVT, SDTCisInt, SDTCisFP, SDTCisSameAs, SDTCisVTSmallerThanOp + SDTCisVT, SDTCisInt, SDTCisFP, SDTCisSameAs, SDTCisVTSmallerThanOp, + SDTCisOpSmallerThanOp } ConstraintType; union { // The discriminated union. @@ -47,6 +48,9 @@ struct { unsigned OtherOperandNum; } SDTCisVTSmallerThanOp_Info; + struct { + unsigned BigOperandNum; + } SDTCisOpSmallerThanOp_Info; } x; /// ApplyTypeConstraint - Given a node in a pattern, apply this type From lattner at cs.uiuc.edu Thu Oct 13 23:55:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 23:55:21 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200510140455.XAA23124@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.1 -> 1.2 --- Log message: add a new SDTCisOpSmallerThanOp type constraint, and implement fround/fextend in terms of it --- Diffs of the changes: (+13 -0) TargetSelectionDAG.td | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.1 llvm/lib/Target/TargetSelectionDAG.td:1.2 --- llvm/lib/Target/TargetSelectionDAG.td:1.1 Mon Oct 10 01:00:30 2005 +++ llvm/lib/Target/TargetSelectionDAG.td Thu Oct 13 23:55:10 2005 @@ -45,6 +45,10 @@ int OtherOperandNum = OtherOp; } +class SDTCisOpSmallerThanOp : SDTypeConstraint{ + int BigOperandNum = BigOp; +} + //===----------------------------------------------------------------------===// // Selection DAG Type Profile definitions. // @@ -77,6 +81,12 @@ def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc SDTCisSameAs<0, 1>, SDTCisFP<0> ]>; +def SDTFPRoundOp : SDTypeProfile<1, 1, [ // fround + SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1> +]>; +def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fextend + SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0> +]>; def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>, SDTCisVTSmallerThanOp<2, 1> @@ -136,6 +146,9 @@ def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; +def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; +def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; + def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; From lattner at cs.uiuc.edu Thu Oct 13 23:56:02 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 13 Oct 2005 23:56:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200510140456.XAA23182@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.119 -> 1.120 --- Log message: Add patterns for FP round/extend --- Diffs of the changes: (+2 -2) PowerPCInstrInfo.td | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.119 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.120 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.119 Mon Oct 10 01:01:00 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Thu Oct 13 23:55:50 2005 @@ -424,7 +424,7 @@ []>; def FRSP : XForm_26<63, 12, (ops F4RC:$frD, F8RC:$frB), "frsp $frD, $frB", - []>; + [(set F4RC:$frD, (fround F8RC:$frB))]>; def FSQRT : XForm_26<63, 22, (ops F8RC:$frD, F8RC:$frB), "fsqrt $frD, $frB", [(set F8RC:$frD, (fsqrt F8RC:$frB))]>; @@ -441,7 +441,7 @@ []>; // (set F8RC:$frD, F8RC:$frB) def FMRSD : XForm_26<63, 72, (ops F8RC:$frD, F4RC:$frB), "fmr $frD, $frB", - []>; // (set F8RC:$frD, (fpextend F4RC:$frB)) + [(set F8RC:$frD, (fextend F4RC:$frB))]>; // These are artificially split into two different forms, for 4/8 byte FP. def FABSS : XForm_26<63, 264, (ops F4RC:$frD, F4RC:$frB), From lattner at cs.uiuc.edu Fri Oct 14 00:08:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 00:08:49 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200510140508.AAA23287@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.53 -> 1.54 --- Log message: simplify the code a bit --- Diffs of the changes: (+18 -26) DAGISelEmitter.cpp | 44 ++++++++++++++++++-------------------------- 1 files changed, 18 insertions(+), 26 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.53 llvm/utils/TableGen/DAGISelEmitter.cpp:1.54 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.53 Thu Oct 13 23:53:53 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Oct 14 00:08:37 2005 @@ -63,6 +63,16 @@ return N->getChild(OpNo-NumResults); } +template +static std::vector +FilterVTs(const std::vector &InVTs, T Filter) { + std::vector Result; + for (unsigned i = 0, e = InVTs.size(); i != e; ++i) + if (Filter(InVTs[i])) + Result.push_back(InVTs[i]); + return Result; +} + /// ApplyTypeConstraint - Given a node in a pattern, apply this type /// constraint to the nodes operands. This returns true if it makes a /// change, false otherwise. If a type contradiction is found, throw an @@ -94,21 +104,12 @@ NodeToApply->UpdateNodeType(MVT::i1, TP); // throw an error. // If there is only one integer type supported, this must be it. - const std::vector &VTs = CGT.getLegalValueTypes(); - MVT::ValueType VT = MVT::LAST_VALUETYPE; - for (unsigned i = 0, e = VTs.size(); i != e; ++i) - if (MVT::isInteger(VTs[i])) { - if (VT == MVT::LAST_VALUETYPE) - VT = VTs[i]; // First integer type we've found. - else { - VT = MVT::LAST_VALUETYPE; - break; - } - } + std::vector IntVTs = + FilterVTs(CGT.getLegalValueTypes(), MVT::isInteger); // If we found exactly one supported integer type, apply it. - if (VT != MVT::LAST_VALUETYPE) - return NodeToApply->UpdateNodeType(VT, TP); + if (IntVTs.size() == 1) + return NodeToApply->UpdateNodeType(IntVTs[0], TP); return false; } case SDTCisFP: { @@ -117,21 +118,12 @@ NodeToApply->UpdateNodeType(MVT::f32, TP); // throw an error. // If there is only one FP type supported, this must be it. - const std::vector &VTs = CGT.getLegalValueTypes(); - MVT::ValueType VT = MVT::LAST_VALUETYPE; - for (unsigned i = 0, e = VTs.size(); i != e; ++i) - if (MVT::isFloatingPoint(VTs[i])) { - if (VT == MVT::LAST_VALUETYPE) - VT = VTs[i]; // First integer type we've found. - else { - VT = MVT::LAST_VALUETYPE; - break; - } - } + std::vector FPVTs = + FilterVTs(CGT.getLegalValueTypes(), MVT::isFloatingPoint); // If we found exactly one supported FP type, apply it. - if (VT != MVT::LAST_VALUETYPE) - return NodeToApply->UpdateNodeType(VT, TP); + if (FPVTs.size() == 1) + return NodeToApply->UpdateNodeType(FPVTs[0], TP); return false; } case SDTCisSameAs: { From lattner at cs.uiuc.edu Fri Oct 14 01:12:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 01:12:15 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200510140612.BAA23528@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.54 -> 1.55 DAGISelEmitter.h updated: 1.31 -> 1.32 --- Log message: Fairly serious rework of the typing code to add new int/fp lattice values. Overall, no functionality change yet though. --- Diffs of the changes: (+109 -60) DAGISelEmitter.cpp | 136 ++++++++++++++++++++++++++++++++--------------------- DAGISelEmitter.h | 33 +++++++++--- 2 files changed, 109 insertions(+), 60 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.54 llvm/utils/TableGen/DAGISelEmitter.cpp:1.55 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.54 Fri Oct 14 00:08:37 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Oct 14 01:12:03 2005 @@ -20,6 +20,35 @@ using namespace llvm; //===----------------------------------------------------------------------===// +// Helpers for working with extended types. + +/// FilterVTs - Filter a list of VT's according to a predicate. +/// +template +static std::vector +FilterVTs(const std::vector &InVTs, T Filter) { + std::vector Result; + for (unsigned i = 0, e = InVTs.size(); i != e; ++i) + if (Filter(InVTs[i])) + Result.push_back(InVTs[i]); + return Result; +} + +/// isExtIntegerVT - Return true if the specified extended value type is +/// integer, or isInt. +static bool isExtIntegerVT(unsigned char VT) { + return VT == MVT::isInt || + (VT < MVT::LAST_VALUETYPE && MVT::isInteger((MVT::ValueType)VT)); +} + +/// isExtFloatingPointVT - Return true if the specified extended value type is +/// floating point, or isFP. +static bool isExtFloatingPointVT(unsigned char VT) { + return VT == MVT::isFP || + (VT < MVT::LAST_VALUETYPE && MVT::isFloatingPoint((MVT::ValueType)VT)); +} + +//===----------------------------------------------------------------------===// // SDTypeConstraint implementation // @@ -63,16 +92,6 @@ return N->getChild(OpNo-NumResults); } -template -static std::vector -FilterVTs(const std::vector &InVTs, T Filter) { - std::vector Result; - for (unsigned i = 0, e = InVTs.size(); i != e; ++i) - if (Filter(InVTs[i])) - Result.push_back(InVTs[i]); - return Result; -} - /// ApplyTypeConstraint - Given a node in a pattern, apply this type /// constraint to the nodes operands. This returns true if it makes a /// change, false otherwise. If a type contradiction is found, throw an @@ -100,9 +119,6 @@ // Operand must be a particular type. return NodeToApply->UpdateNodeType(x.SDTCisVT_Info.VT, TP); case SDTCisInt: { - if (NodeToApply->hasTypeSet() && !MVT::isInteger(NodeToApply->getType())) - NodeToApply->UpdateNodeType(MVT::i1, TP); // throw an error. - // If there is only one integer type supported, this must be it. std::vector IntVTs = FilterVTs(CGT.getLegalValueTypes(), MVT::isInteger); @@ -110,13 +126,9 @@ // If we found exactly one supported integer type, apply it. if (IntVTs.size() == 1) return NodeToApply->UpdateNodeType(IntVTs[0], TP); - return false; + return NodeToApply->UpdateNodeType(MVT::isInt, TP); } case SDTCisFP: { - if (NodeToApply->hasTypeSet() && - !MVT::isFloatingPoint(NodeToApply->getType())) - NodeToApply->UpdateNodeType(MVT::f32, TP); // throw an error. - // If there is only one FP type supported, this must be it. std::vector FPVTs = FilterVTs(CGT.getLegalValueTypes(), MVT::isFloatingPoint); @@ -124,13 +136,13 @@ // If we found exactly one supported FP type, apply it. if (FPVTs.size() == 1) return NodeToApply->UpdateNodeType(FPVTs[0], TP); - return false; + return NodeToApply->UpdateNodeType(MVT::isFP, TP); } case SDTCisSameAs: { TreePatternNode *OtherNode = getOperandNum(x.SDTCisSameAs_Info.OtherOperandNum, N, NumResults); - return NodeToApply->UpdateNodeType(OtherNode->getType(), TP) | - OtherNode->UpdateNodeType(NodeToApply->getType(), TP); + return NodeToApply->UpdateNodeType(OtherNode->getExtType(), TP) | + OtherNode->UpdateNodeType(NodeToApply->getExtType(), TP); } case SDTCisVTSmallerThanOp: { // The NodeToApply must be a leaf node that is a VT. OtherOperandNum must @@ -147,9 +159,12 @@ TreePatternNode *OtherNode = getOperandNum(x.SDTCisVTSmallerThanOp_Info.OtherOperandNum, N,NumResults); - if (OtherNode->hasTypeSet() && - (!MVT::isInteger(OtherNode->getType()) || - OtherNode->getType() <= VT)) + + // It must be integer. + bool MadeChange = false; + MadeChange |= OtherNode->UpdateNodeType(MVT::isInt, TP); + + if (OtherNode->hasTypeSet() && OtherNode->getType() <= VT) OtherNode->UpdateNodeType(MVT::Other, TP); // Throw an error. return false; } @@ -216,13 +231,27 @@ /// information. If N already contains a conflicting type, then throw an /// exception. This returns true if any information was updated. /// -bool TreePatternNode::UpdateNodeType(MVT::ValueType VT, TreePattern &TP) { - if (VT == MVT::LAST_VALUETYPE || getType() == VT) return false; - if (getType() == MVT::LAST_VALUETYPE) { +bool TreePatternNode::UpdateNodeType(unsigned char VT, TreePattern &TP) { + if (VT == MVT::isUnknown || getExtType() == VT) return false; + if (getExtType() == MVT::isUnknown) { setType(VT); return true; } + // If we are told this is to be an int or FP type, and it already is, ignore + // the advice. + if ((VT == MVT::isInt && isExtIntegerVT(getExtType())) || + (VT == MVT::isFP && isExtFloatingPointVT(getExtType()))) + return false; + + // If we know this is an int or fp type, and we are told it is a specific one, + // take the advice. + if ((getExtType() == MVT::isInt && isExtIntegerVT(VT)) || + (getExtType() == MVT::isFP && isExtFloatingPointVT(VT))) { + setType(VT); + return true; + } + TP.error("Type inference contradiction found in node " + getOperator()->getName() + "!"); return true; // unreachable @@ -236,12 +265,13 @@ OS << "(" << getOperator()->getName(); } - if (getType() == MVT::Other) - OS << ":Other"; - else if (getType() == MVT::LAST_VALUETYPE) - ;//OS << ":?"; - else - OS << ":" << getType(); + switch (getExtType()) { + case MVT::Other: OS << ":Other"; break; + case MVT::isInt: OS << ":isInt"; break; + case MVT::isFP : OS << ":isFP"; break; + case MVT::isUnknown: ; /*OS << ":?";*/ break; + default: OS << ":" << getType(); break; + } if (!isLeaf()) { if (getNumChildren() != 0) { @@ -273,7 +303,7 @@ /// that are otherwise identical are considered isomorphic. bool TreePatternNode::isIsomorphicTo(const TreePatternNode *N) const { if (N == this) return true; - if (N->isLeaf() != isLeaf() || getType() != N->getType() || + if (N->isLeaf() != isLeaf() || getExtType() != N->getExtType() || getPredicateFn() != N->getPredicateFn() || getTransformFn() != N->getTransformFn()) return false; @@ -307,7 +337,7 @@ New = new TreePatternNode(getOperator(), CChildren); } New->setName(getName()); - New->setType(getType()); + New->setType(getExtType()); New->setPredicateFn(getPredicateFn()); New->setTransformFn(getTransformFn()); return New; @@ -383,23 +413,24 @@ /// type which should be applied to it. This infer the type of register /// references from the register file information, for example. /// -static MVT::ValueType getIntrinsicType(Record *R, bool NotRegisters, TreePattern &TP) { +static unsigned char getIntrinsicType(Record *R, bool NotRegisters, + TreePattern &TP) { // Check to see if this is a register or a register class... if (R->isSubClassOf("RegisterClass")) { - if (NotRegisters) return MVT::LAST_VALUETYPE; + if (NotRegisters) return MVT::isUnknown; return getValueType(R->getValueAsDef("RegType")); } else if (R->isSubClassOf("PatFrag")) { // Pattern fragment types will be resolved when they are inlined. - return MVT::LAST_VALUETYPE; + return MVT::isUnknown; } else if (R->isSubClassOf("Register")) { assert(0 && "Explicit registers not handled here yet!\n"); - return MVT::LAST_VALUETYPE; + return MVT::isUnknown; } else if (R->isSubClassOf("ValueType")) { // Using a VTSDNode. return MVT::Other; } else if (R->getName() == "node") { // Placeholder. - return MVT::LAST_VALUETYPE; + return MVT::isUnknown; } TP.error("Unknown node flavor used in pattern: " + R->getName()); @@ -426,8 +457,8 @@ MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters); // Types of operands must match. - MadeChange |= getChild(0)->UpdateNodeType(getChild(1)->getType(), TP); - MadeChange |= getChild(1)->UpdateNodeType(getChild(0)->getType(), TP); + MadeChange |= getChild(0)->UpdateNodeType(getChild(1)->getExtType(), TP); + MadeChange |= getChild(1)->UpdateNodeType(getChild(0)->getExtType(), TP); MadeChange |= UpdateNodeType(MVT::isVoid, TP); return MadeChange; } else if (getOperator()->isSubClassOf("SDNode")) { @@ -462,8 +493,8 @@ if (getNumChildren() != 1) TP.error("Node transform '" + getOperator()->getName() + "' requires one operand!"); - bool MadeChange = UpdateNodeType(getChild(0)->getType(), TP); - MadeChange |= getChild(0)->UpdateNodeType(getType(), TP); + bool MadeChange = UpdateNodeType(getChild(0)->getExtType(), TP); + MadeChange |= getChild(0)->UpdateNodeType(getExtType(), TP); return MadeChange; } } @@ -825,7 +856,7 @@ // Ensure that the inputs agree if we've already seen this input. if (Rec != SlotRec) I->error("All $" + Pat->getName() + " inputs must agree with each other"); - if (Slot->getType() != Pat->getType()) + if (Slot->getExtType() != Pat->getExtType()) I->error("All $" + Pat->getName() + " inputs must agree with each other"); } return true; @@ -847,7 +878,7 @@ // If this is not a set, verify that the children nodes are not void typed, // and recurse. for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) { - if (Pat->getChild(i)->getType() == MVT::isVoid) + if (Pat->getChild(i)->getExtType() == MVT::isVoid) I->error("Cannot have void nodes inside of patterns!"); FindPatternInputsAndOutputs(I, Pat->getChild(i), InstInputs, InstResults); } @@ -933,7 +964,7 @@ // fill in the InstResults map. for (unsigned j = 0, e = I->getNumTrees(); j != e; ++j) { TreePatternNode *Pat = I->getTree(j); - if (Pat->getType() != MVT::isVoid) { + if (Pat->getExtType() != MVT::isVoid) { I->dump(); I->error("Top-level forms in instruction pattern should have" " void types"); @@ -993,7 +1024,7 @@ " does not appear in the instruction pattern"); TreePatternNode *InVal = InstInputsCheck[OpName]; InstInputsCheck.erase(OpName); // It occurred, remove from map. - if (CGI.OperandList[i].Ty != InVal->getType()) + if (CGI.OperandList[i].Ty != InVal->getExtType()) I->error("Operand $" + OpName + "'s type disagrees between the operand and pattern"); OperandTypes.push_back(InVal->getType()); @@ -1133,7 +1164,7 @@ R->setName(Orig->getName()); R->setPredicateFn(Orig->getPredicateFn()); R->setTransformFn(Orig->getTransformFn()); - R->setType(Orig->getType()); + R->setType(Orig->getExtType()); // If this pattern cannot every match, do not include it as a variant. std::string ErrString; @@ -1357,14 +1388,15 @@ /// patterns before small ones. This is used to determine the size of a /// pattern. static unsigned getPatternSize(TreePatternNode *P) { - assert(MVT::isInteger(P->getType()) || MVT::isFloatingPoint(P->getType()) && + assert(isExtIntegerVT(P->getExtType()) || + isExtFloatingPointVT(P->getExtType()) && "Not a valid pattern node to size!"); unsigned Size = 1; // The node itself. // Count children in the count if they are also nodes. for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) { TreePatternNode *Child = P->getChild(i); - if (!Child->isLeaf() && Child->getType() != MVT::Other) + if (!Child->isLeaf() && Child->getExtType() != MVT::Other) Size += getPatternSize(Child); } @@ -1557,7 +1589,7 @@ /// RemoveAllTypes - A quick recursive walk over a pattern which removes all /// type information from it. static void RemoveAllTypes(TreePatternNode *N) { - N->setType(MVT::LAST_VALUETYPE); + N->setType(MVT::isUnknown); if (!N->isLeaf()) for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) RemoveAllTypes(N->getChild(i)); Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.31 llvm/utils/TableGen/DAGISelEmitter.h:1.32 --- llvm/utils/TableGen/DAGISelEmitter.h:1.31 Thu Oct 13 23:53:53 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Fri Oct 14 01:12:03 2005 @@ -27,6 +27,16 @@ class TreePatternNode; class DAGISelEmitter; + /// MVT::DAGISelGenValueType - These are some extended forms of MVT::ValueType + /// that we use as lattice values during type inferrence. + namespace MVT { + enum DAGISelGenValueType { + isFP = MVT::LAST_VALUETYPE, + isInt, + isUnknown + }; + } + /// SDTypeConstraint - This is a discriminated union of constraints, /// corresponding to the SDTypeConstraint tablegen class in Target.td. struct SDTypeConstraint { @@ -115,8 +125,8 @@ class TreePatternNode { /// The inferred type for this node, or MVT::LAST_VALUETYPE if it hasn't /// been determined yet. - MVT::ValueType Ty; - + unsigned char Ty; + /// Operator - The Record for the operator if this is an interior node (not /// a leaf). Record *Operator; @@ -140,19 +150,26 @@ std::vector Children; public: TreePatternNode(Record *Op, const std::vector &Ch) - : Ty(MVT::LAST_VALUETYPE), Operator(Op), Val(0), TransformFn(0), + : Ty(MVT::isUnknown), Operator(Op), Val(0), TransformFn(0), Children(Ch) {} TreePatternNode(Init *val) // leaf ctor - : Ty(MVT::LAST_VALUETYPE), Operator(0), Val(val), TransformFn(0) {} + : Ty(MVT::isUnknown), Operator(0), Val(val), TransformFn(0) {} ~TreePatternNode(); const std::string &getName() const { return Name; } void setName(const std::string &N) { Name = N; } bool isLeaf() const { return Val != 0; } - bool hasTypeSet() const { return Ty != MVT::LAST_VALUETYPE; } - MVT::ValueType getType() const { return Ty; } - void setType(MVT::ValueType VT) { Ty = VT; } + bool hasTypeSet() const { return Ty < MVT::LAST_VALUETYPE; } + bool isTypeCompletelyUnknown() const { + return Ty == MVT::isUnknown; + } + MVT::ValueType getType() const { + assert(hasTypeSet() && "Doesn't have a type yet!"); + return (MVT::ValueType)Ty; + } + unsigned char getExtType() const { return Ty; } + void setType(unsigned char VT) { Ty = VT; } Init *getLeafValue() const { assert(isLeaf()); return Val; } Record *getOperator() const { assert(!isLeaf()); return Operator; } @@ -204,7 +221,7 @@ /// information. If N already contains a conflicting type, then throw an /// exception. This returns true if any information was updated. /// - bool UpdateNodeType(MVT::ValueType VT, TreePattern &TP); + bool UpdateNodeType(unsigned char EVT, TreePattern &TP); /// ContainsUnresolvedType - Return true if this tree contains any /// unresolved types. From lattner at cs.uiuc.edu Fri Oct 14 01:25:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 01:25:12 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200510140625.BAA23625@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.55 -> 1.56 --- Log message: Now that we have int/fp lattice values, implement the SDTCisOpSmallerThanOp type constraint. This lets tblgen realize that it doesn't need any dynamic type checks for fextend/fround on PPC (and many other targets), because there are only two fp types. --- Diffs of the changes: (+41 -2) DAGISelEmitter.cpp | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 41 insertions(+), 2 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.55 llvm/utils/TableGen/DAGISelEmitter.cpp:1.56 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.55 Fri Oct 14 01:12:03 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Oct 14 01:25:00 2005 @@ -169,8 +169,47 @@ return false; } case SDTCisOpSmallerThanOp: { - // TODO - return false; + TreePatternNode *BigOperand = + getOperandNum(x.SDTCisOpSmallerThanOp_Info.BigOperandNum, N, NumResults); + + // Both operands must be integer or FP, but we don't care which. + bool MadeChange = false; + + if (isExtIntegerVT(NodeToApply->getExtType())) + MadeChange |= BigOperand->UpdateNodeType(MVT::isInt, TP); + else if (isExtFloatingPointVT(NodeToApply->getExtType())) + MadeChange |= BigOperand->UpdateNodeType(MVT::isFP, TP); + if (isExtIntegerVT(BigOperand->getExtType())) + MadeChange |= NodeToApply->UpdateNodeType(MVT::isInt, TP); + else if (isExtFloatingPointVT(BigOperand->getExtType())) + MadeChange |= NodeToApply->UpdateNodeType(MVT::isFP, TP); + + std::vector VTs = CGT.getLegalValueTypes(); + + if (isExtIntegerVT(NodeToApply->getExtType())) { + VTs = FilterVTs(VTs, MVT::isInteger); + } else if (isExtFloatingPointVT(NodeToApply->getExtType())) { + VTs = FilterVTs(VTs, MVT::isFloatingPoint); + } else { + VTs.clear(); + } + + switch (VTs.size()) { + default: // Too many VT's to pick from. + case 0: break; // No info yet. + case 1: + // Only one VT of this flavor. Cannot ever satisify the constraints. + return NodeToApply->UpdateNodeType(MVT::Other, TP); // throw + case 2: + // If we have exactly two possible types, the little operand must be the + // small one, the big operand should be the big one. Common with + // float/double for example. + assert(VTs[0] < VTs[1] && "Should be sorted!"); + MadeChange |= NodeToApply->UpdateNodeType(VTs[0], TP); + MadeChange |= BigOperand->UpdateNodeType(VTs[1], TP); + break; + } + return MadeChange; } } return false; From lattner at cs.uiuc.edu Fri Oct 14 01:26:40 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 01:26:40 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200510140626.BAA23707@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.99 -> 1.100 --- Log message: These are now autogenerated --- Diffs of the changes: (+0 -12) PPC32ISelDAGToDAG.cpp | 12 ------------ 1 files changed, 12 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.99 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.100 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.99 Sun Oct 9 00:36:17 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Fri Oct 14 01:26:29 2005 @@ -1309,18 +1309,6 @@ else CurDAG->SelectNodeTo(N, PPC::FABSD, MVT::f64, Select(N->getOperand(0))); return SDOperand(N, 0); - case ISD::FP_EXTEND: - assert(MVT::f64 == N->getValueType(0) && - MVT::f32 == N->getOperand(0).getValueType() && "Illegal FP_EXTEND"); - // We need to emit an FMR to make sure that the result has the right value - // type. - CurDAG->SelectNodeTo(N, PPC::FMRSD, MVT::f64, Select(N->getOperand(0))); - return SDOperand(N, 0); - case ISD::FP_ROUND: - assert(MVT::f32 == N->getValueType(0) && - MVT::f64 == N->getOperand(0).getValueType() && "Illegal FP_ROUND"); - CurDAG->SelectNodeTo(N, PPC::FRSP, MVT::f32, Select(N->getOperand(0))); - return SDOperand(N, 0); case ISD::FNEG: { SDOperand Val = Select(N->getOperand(0)); MVT::ValueType Ty = N->getValueType(0); From lattner at cs.uiuc.edu Fri Oct 14 01:32:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 01:32:09 -0500 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200510140632.BAA23782@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.326 -> 1.327 --- Log message: Make sure targets depend on TargetSelectionDAG.td --- Diffs of the changes: (+1 -1) Makefile.rules | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.326 llvm/Makefile.rules:1.327 --- llvm/Makefile.rules:1.326 Tue Oct 4 19:28:41 2005 +++ llvm/Makefile.rules Fri Oct 14 01:31:58 2005 @@ -1100,7 +1100,7 @@ ifdef TARGET -TDFiles := $(strip $(wildcard $(PROJ_SRC_DIR)/*.td) $(LLVM_SRC_ROOT)/lib/Target/Target.td) +TDFiles := $(strip $(wildcard $(PROJ_SRC_DIR)/*.td) $(LLVM_SRC_ROOT)/lib/Target/Target.td $(LLVM_SRC_ROOT)/lib/Target/TargetSelectionDAG.td) INCFiles := $(filter %.inc,$(BUILT_SOURCES)) INCTMPFiles := $(INCFiles:%=$(ObjDir)/%.tmp) .PRECIOUS: $(INCTMPFiles) $(INCFiles) From lattner at cs.uiuc.edu Fri Oct 14 01:40:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 01:40:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200510140640.BAA23889@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.2 -> 1.3 --- Log message: add the integer truncate/extension operations --- Diffs of the changes: (+14 -3) TargetSelectionDAG.td | 17 ++++++++++++++--- 1 files changed, 14 insertions(+), 3 deletions(-) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.2 llvm/lib/Target/TargetSelectionDAG.td:1.3 --- llvm/lib/Target/TargetSelectionDAG.td:1.2 Thu Oct 13 23:55:10 2005 +++ llvm/lib/Target/TargetSelectionDAG.td Fri Oct 14 01:40:20 2005 @@ -78,6 +78,12 @@ def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz SDTCisSameAs<0, 1>, SDTCisInt<0> ]>; +def SDTIntExtendOp : SDTypeProfile<1, 1, [ // sext, zext, anyext + SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0> +]>; +def SDTIntTruncOp : SDTypeProfile<1, 1, [ // trunc + SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1> +]>; def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc SDTCisSameAs<0, 1>, SDTCisFP<0> ]>; @@ -137,6 +143,14 @@ [SDNPCommutative, SDNPAssociative]>; def xor : SDNode<"ISD::XOR" , SDTIntBinOp, [SDNPCommutative, SDNPAssociative]>; + +def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; +def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; +def sext : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>; +def zext : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>; +def anyext : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>; +def trunc : SDNode<"ISD::TRUNCATE" , SDTIntTruncOp>; + def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>; def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>; def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; @@ -149,9 +163,6 @@ def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; -def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; -def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; - //===----------------------------------------------------------------------===// // Selection DAG Node Transformation Functions. // From natebegeman at mac.com Fri Oct 14 13:58:57 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 14 Oct 2005 13:58:57 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32.td PowerPC.td PowerPCRegisterInfo.td PPC32RegisterInfo.td Message-ID: <200510141858.NAA27668@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32.td updated: 1.4 -> 1.5 PowerPC.td updated: 1.13 -> 1.14 PowerPCRegisterInfo.td updated: 1.16 -> 1.17 PPC32RegisterInfo.td (r1.8) removed --- Log message: Remove an unnecsesary file. PPC32 and PPC64 share architected registers. We will decide with subtarget support whether we ever use an i64 register class. --- Diffs of the changes: (+38 -2) PPC32.td | 2 +- PowerPC.td | 2 +- PowerPCRegisterInfo.td | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32.td diff -u llvm/lib/Target/PowerPC/PPC32.td:1.4 llvm/lib/Target/PowerPC/PPC32.td:1.5 --- llvm/lib/Target/PowerPC/PPC32.td:1.4 Thu Dec 16 10:31:57 2004 +++ llvm/lib/Target/PowerPC/PPC32.td Fri Oct 14 13:58:46 2005 @@ -18,7 +18,7 @@ // Register File Description //===----------------------------------------------------------------------===// -include "PPC32RegisterInfo.td" +include "PowerPCRegisterInfo.td" include "PowerPCInstrInfo.td" def PPC32 : Target { Index: llvm/lib/Target/PowerPC/PowerPC.td diff -u llvm/lib/Target/PowerPC/PowerPC.td:1.13 llvm/lib/Target/PowerPC/PowerPC.td:1.14 --- llvm/lib/Target/PowerPC/PowerPC.td:1.13 Thu Sep 29 19:05:05 2005 +++ llvm/lib/Target/PowerPC/PowerPC.td Fri Oct 14 13:58:46 2005 @@ -18,7 +18,7 @@ // Register File Description //===----------------------------------------------------------------------===// -include "PPC32RegisterInfo.td" +include "PowerPCRegisterInfo.td" include "PowerPCInstrInfo.td" def PowerPC : Target { Index: llvm/lib/Target/PowerPC/PowerPCRegisterInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCRegisterInfo.td:1.16 llvm/lib/Target/PowerPC/PowerPCRegisterInfo.td:1.17 --- llvm/lib/Target/PowerPC/PowerPCRegisterInfo.td:1.16 Mon Aug 22 17:32:13 2005 +++ llvm/lib/Target/PowerPC/PowerPCRegisterInfo.td Fri Oct 14 13:58:46 2005 @@ -84,3 +84,39 @@ // Count register def CTR : SPR<3, "ctr">; +/// Register classes +// Allocate volatiles first +// then nonvolatiles in reverse order since stmw/lmw save from rN to r31 +def GPRC : RegisterClass<"PPC32", i32, 32, + [R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, + R30, R29, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17, + R16, R15, R14, R13, R31, R0, R1, LR]> +{ + let MethodProtos = [{ + iterator allocation_order_begin(MachineFunction &MF) const; + iterator allocation_order_end(MachineFunction &MF) const; + }]; + let MethodBodies = [{ + GPRCClass::iterator + GPRCClass::allocation_order_begin(MachineFunction &MF) const { + return begin() + ((TargetAIX == PPCTarget) ? 1 : 0); + } + GPRCClass::iterator + GPRCClass::allocation_order_end(MachineFunction &MF) const { + if (hasFP(MF)) + return end()-4; + else + return end()-3; + } + }]; +} + +def F8RC : RegisterClass<"PPC32", f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7, + F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, + F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>; +def F4RC : RegisterClass<"PPC32", f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7, + F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, + F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>; + + +def CRRC : RegisterClass<"PPC32", i32, 32, [CR0, CR1, CR5, CR6, CR7, CR2, CR3, CR4]>; From natebegeman at mac.com Fri Oct 14 17:06:11 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 14 Oct 2005 17:06:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp X86InstrInfo.cpp X86InstrInfo.td X86RegisterInfo.cpp X86RegisterInfo.td Message-ID: <200510142206.RAA30913@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.181 -> 1.182 X86InstrInfo.cpp updated: 1.40 -> 1.41 X86InstrInfo.td updated: 1.134 -> 1.135 X86RegisterInfo.cpp updated: 1.111 -> 1.112 X86RegisterInfo.td updated: 1.21 -> 1.22 --- Log message: Properly split f32 and f64 into separate register classes for scalar sse fp fixing a bunch of nasty hackery --- Diffs of the changes: (+77 -78) X86ISelPattern.cpp | 8 +-- X86InstrInfo.cpp | 2 X86InstrInfo.td | 120 ++++++++++++++++++++++++---------------------------- X86RegisterInfo.cpp | 16 ++++-- X86RegisterInfo.td | 9 ++- 5 files changed, 77 insertions(+), 78 deletions(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.181 llvm/lib/Target/X86/X86ISelPattern.cpp:1.182 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.181 Sun Oct 2 11:29:36 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Fri Oct 14 17:06:00 2005 @@ -184,8 +184,8 @@ if (X86ScalarSSE) { // Set up the FP register classes. - addRegisterClass(MVT::f32, X86::RXMMRegisterClass); - addRegisterClass(MVT::f64, X86::RXMMRegisterClass); + addRegisterClass(MVT::f32, X86::V4F4RegisterClass); + addRegisterClass(MVT::f64, X86::V2F8RegisterClass); // SSE has no load+extend ops setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); @@ -4192,10 +4192,10 @@ case MVT::i8: Opc = X86::MOV8rr; break; case MVT::i16: Opc = X86::MOV16rr; break; case MVT::i32: Opc = X86::MOV32rr; break; - case MVT::f32: Opc = X86::MOVAPSrr; break; + case MVT::f32: Opc = X86::MOVSSrr; break; case MVT::f64: if (X86ScalarSSE) { - Opc = X86::MOVAPDrr; + Opc = X86::MOVSDrr; } else { Opc = X86::FpMOV; ContainsFPCode = true; Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.40 llvm/lib/Target/X86/X86InstrInfo.cpp:1.41 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.40 Fri Jul 15 21:00:20 2005 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Fri Oct 14 17:06:00 2005 @@ -28,7 +28,7 @@ unsigned& destReg) const { MachineOpCode oc = MI.getOpcode(); if (oc == X86::MOV8rr || oc == X86::MOV16rr || oc == X86::MOV32rr || - oc == X86::FpMOV || oc == X86::MOVAPDrr || oc == X86::MOVAPSrr) { + oc == X86::FpMOV || oc == X86::MOVSSrr || oc == X86::MOVSDrr) { assert(MI.getNumOperands() == 2 && MI.getOperand(0).isRegister() && MI.getOperand(1).isRegister() && Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.134 llvm/lib/Target/X86/X86InstrInfo.td:1.135 --- llvm/lib/Target/X86/X86InstrInfo.td:1.134 Wed Sep 14 16:10:24 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Fri Oct 14 17:06:00 2005 @@ -1408,142 +1408,134 @@ // XMM Floating point support (requires SSE2) //===----------------------------------------------------------------------===// -def MOVSSrm : I<0x10, MRMSrcMem, (ops RXMM:$dst, f32mem:$src), +def MOVSSrr : I<0x10, MRMSrcReg, (ops V4F4:$dst, V4F4:$src), "movss {$src, $dst|$dst, $src}">, XS; -def MOVSSmr : I<0x11, MRMDestMem, (ops f32mem:$dst, RXMM:$src), +def MOVSSrm : I<0x10, MRMSrcMem, (ops V4F4:$dst, f32mem:$src), "movss {$src, $dst|$dst, $src}">, XS; -def MOVSDrm : I<0x10, MRMSrcMem, (ops RXMM:$dst, f64mem:$src), +def MOVSSmr : I<0x11, MRMDestMem, (ops f32mem:$dst, V4F4:$src), + "movss {$src, $dst|$dst, $src}">, XS; +def MOVSDrr : I<0x10, MRMSrcReg, (ops V2F8:$dst, V2F8:$src), + "movsd {$src, $dst|$dst, $src}">, XD; +def MOVSDrm : I<0x10, MRMSrcMem, (ops V2F8:$dst, f64mem:$src), "movsd {$src, $dst|$dst, $src}">, XD; -def MOVSDmr : I<0x11, MRMDestMem, (ops f64mem:$dst, RXMM:$src), +def MOVSDmr : I<0x11, MRMDestMem, (ops f64mem:$dst, V2F8:$src), "movsd {$src, $dst|$dst, $src}">, XD; -def MOVAPSrr: I<0x28, MRMSrcReg, (ops RXMM:$dst, RXMM:$src), - "movaps {$src, $dst|$dst, $src}">, TB; -def MOVAPSrm: I<0x28, MRMSrcMem, (ops RXMM:$dst, f32mem:$src), - "movaps {$src, $dst|$dst, $src}">, TB; -def MOVAPSmr: I<0x29, MRMDestMem, (ops f32mem:$dst, RXMM:$src), - "movaps {$src, $dst|$dst, $src}">, TB; -def MOVAPDrr: I<0x28, MRMSrcReg, (ops RXMM:$dst, RXMM:$src), - "movapd {$src, $dst|$dst, $src}">, TB, OpSize; -def MOVAPDrm: I<0x28, MRMSrcMem, (ops RXMM:$dst, f64mem:$src), - "movapd {$src, $dst|$dst, $src}">, TB, OpSize; -def MOVAPDmr: I<0x29, MRMDestMem, (ops f64mem:$dst, RXMM:$src), - "movapd {$src, $dst|$dst, $src}">, TB, OpSize; -def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, RXMM:$src), +def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, V2F8:$src), "cvttsd2si {$src, $dst|$dst, $src}">, XD; def CVTTSD2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src), "cvttsd2si {$src, $dst|$dst, $src}">, XD; -def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, RXMM:$src), +def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, V4F4:$src), "cvttss2si {$src, $dst|$dst, $src}">, XS; def CVTTSS2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f32mem:$src), "cvttss2si {$src, $dst|$dst, $src}">, XS; -def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops RXMM:$dst, RXMM:$src), +def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops V4F4:$dst, V2F8:$src), "cvtsd2ss {$src, $dst|$dst, $src}">, XS; -def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops RXMM:$dst, f64mem:$src), +def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops V4F4:$dst, f64mem:$src), "cvtsd2ss {$src, $dst|$dst, $src}">, XS; -def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops RXMM:$dst, RXMM:$src), +def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops V2F8:$dst, V4F4:$src), "cvtss2sd {$src, $dst|$dst, $src}">, XD; -def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops RXMM:$dst, f32mem:$src), +def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops V2F8:$dst, f32mem:$src), "cvtss2sd {$src, $dst|$dst, $src}">, XD; -def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops R32:$dst, RXMM:$src), +def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops V4F4:$dst, R32:$src), "cvtsi2ss {$src, $dst|$dst, $src}">, XS; -def CVTSI2SSrm: I<0x2A, MRMSrcMem, (ops R32:$dst, f32mem:$src), +def CVTSI2SSrm: I<0x2A, MRMSrcMem, (ops V4F4:$dst, i32mem:$src), "cvtsi2ss {$src, $dst|$dst, $src}">, XS; -def CVTSI2SDrr: I<0x2A, MRMSrcReg, (ops R32:$dst, RXMM:$src), +def CVTSI2SDrr: I<0x2A, MRMSrcReg, (ops V2F8:$dst, R32:$src), "cvtsi2sd {$src, $dst|$dst, $src}">, XD; -def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops R32:$dst, f64mem:$src), +def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops V2F8:$dst, i32mem:$src), "cvtsi2sd {$src, $dst|$dst, $src}">, XD; -def SQRTSSrm : I<0x51, MRMSrcMem, (ops RXMM:$dst, f32mem:$src), +def SQRTSSrm : I<0x51, MRMSrcMem, (ops V4F4:$dst, f32mem:$src), "subss {$src, $dst|$dst, $src}">, XS; -def SQRTSSrr : I<0x51, MRMSrcReg, (ops RXMM:$dst, RXMM:$src), +def SQRTSSrr : I<0x51, MRMSrcReg, (ops V4F4:$dst, V4F4:$src), "subss {$src, $dst|$dst, $src}">, XS; -def SQRTSDrm : I<0x51, MRMSrcMem, (ops RXMM:$dst, f64mem:$src), +def SQRTSDrm : I<0x51, MRMSrcMem, (ops V2F8:$dst, f64mem:$src), "subsd {$src, $dst|$dst, $src}">, XD; -def SQRTSDrr : I<0x51, MRMSrcReg, (ops RXMM:$dst, RXMM:$src), +def SQRTSDrr : I<0x51, MRMSrcReg, (ops V2F8:$dst, V2F8:$src), "subsd {$src, $dst|$dst, $src}">, XD; -def UCOMISDrr: I<0x2E, MRMSrcReg, (ops RXMM:$dst, RXMM:$src), +def UCOMISDrr: I<0x2E, MRMSrcReg, (ops V2F8:$dst, V2F8:$src), "ucomisd {$src, $dst|$dst, $src}">, TB, OpSize; -def UCOMISDrm: I<0x2E, MRMSrcMem, (ops RXMM:$dst, f64mem:$src), +def UCOMISDrm: I<0x2E, MRMSrcMem, (ops V2F8:$dst, f64mem:$src), "ucomisd {$src, $dst|$dst, $src}">, TB, OpSize; -def UCOMISSrr: I<0x2E, MRMSrcReg, (ops RXMM:$dst, RXMM:$src), +def UCOMISSrr: I<0x2E, MRMSrcReg, (ops V4F4:$dst, V4F4:$src), "ucomiss {$src, $dst|$dst, $src}">, TB; -def UCOMISSrm: I<0x2E, MRMSrcMem, (ops RXMM:$dst, f32mem:$src), +def UCOMISSrm: I<0x2E, MRMSrcMem, (ops V4F4:$dst, f32mem:$src), "ucomiss {$src, $dst|$dst, $src}">, TB; // Pseudo-instructions that map to fld0 to xorps/xorpd for sse. // FIXME: remove when we can teach regalloc that xor reg, reg is ok. -def FLD0SS : I<0x57, MRMSrcReg, (ops RXMM:$dst), +def FLD0SS : I<0x57, MRMSrcReg, (ops V4F4:$dst), "xorps $dst, $dst">, TB; -def FLD0SD : I<0x57, MRMSrcReg, (ops RXMM:$dst), +def FLD0SD : I<0x57, MRMSrcReg, (ops V2F8:$dst), "xorpd $dst, $dst">, TB, OpSize; let isTwoAddress = 1 in { let isCommutable = 1 in { -def ADDSSrr : I<0x58, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def ADDSSrr : I<0x58, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src), "addss {$src, $dst|$dst, $src}">, XS; -def ADDSDrr : I<0x58, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def ADDSDrr : I<0x58, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src), "addsd {$src, $dst|$dst, $src}">, XD; -def ANDPSrr : I<0x54, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def ANDPSrr : I<0x54, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src), "andps {$src, $dst|$dst, $src}">, TB; -def ANDPDrr : I<0x54, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def ANDPDrr : I<0x54, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src), "andpd {$src, $dst|$dst, $src}">, TB, OpSize; -def MULSSrr : I<0x59, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def MULSSrr : I<0x59, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src), "mulss {$src, $dst|$dst, $src}">, XS; -def MULSDrr : I<0x59, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def MULSDrr : I<0x59, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src), "mulsd {$src, $dst|$dst, $src}">, XD; -def ORPSrr : I<0x56, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def ORPSrr : I<0x56, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src), "orps {$src, $dst|$dst, $src}">, TB; -def ORPDrr : I<0x56, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def ORPDrr : I<0x56, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src), "orpd {$src, $dst|$dst, $src}">, TB, OpSize; -def XORPSrr : I<0x57, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def XORPSrr : I<0x57, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src), "xorps {$src, $dst|$dst, $src}">, TB; -def XORPDrr : I<0x57, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def XORPDrr : I<0x57, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src), "xorpd {$src, $dst|$dst, $src}">, TB, OpSize; } -def ANDNPSrr : I<0x55, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def ANDNPSrr : I<0x55, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src), "andnps {$src, $dst|$dst, $src}">, TB; -def ANDNPDrr : I<0x55, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def ANDNPDrr : I<0x55, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src), "andnpd {$src, $dst|$dst, $src}">, TB, OpSize; -def ADDSSrm : I<0x58, MRMSrcMem, (ops RXMM:$dst, RXMM:$src1, f32mem:$src), +def ADDSSrm : I<0x58, MRMSrcMem, (ops V4F4:$dst, V4F4:$src1, f32mem:$src), "addss {$src, $dst|$dst, $src}">, XS; -def ADDSDrm : I<0x58, MRMSrcMem, (ops RXMM:$dst, RXMM:$src1, f64mem:$src), +def ADDSDrm : I<0x58, MRMSrcMem, (ops V2F8:$dst, V2F8:$src1, f64mem:$src), "addsd {$src, $dst|$dst, $src}">, XD; -def MULSSrm : I<0x59, MRMSrcMem, (ops RXMM:$dst, RXMM:$src1, f32mem:$src), +def MULSSrm : I<0x59, MRMSrcMem, (ops V4F4:$dst, V4F4:$src1, f32mem:$src), "mulss {$src, $dst|$dst, $src}">, XS; -def MULSDrm : I<0x59, MRMSrcMem, (ops RXMM:$dst, RXMM:$src1, f64mem:$src), +def MULSDrm : I<0x59, MRMSrcMem, (ops V2F8:$dst, V2F8:$src1, f64mem:$src), "mulsd {$src, $dst|$dst, $src}">, XD; -def DIVSSrm : I<0x5E, MRMSrcMem, (ops RXMM:$dst, RXMM:$src1, f32mem:$src), +def DIVSSrm : I<0x5E, MRMSrcMem, (ops V4F4:$dst, V4F4:$src1, f32mem:$src), "divss {$src, $dst|$dst, $src}">, XS; -def DIVSSrr : I<0x5E, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def DIVSSrr : I<0x5E, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src), "divss {$src, $dst|$dst, $src}">, XS; -def DIVSDrm : I<0x5E, MRMSrcMem, (ops RXMM:$dst, RXMM:$src1, f64mem:$src), +def DIVSDrm : I<0x5E, MRMSrcMem, (ops V2F8:$dst, V2F8:$src1, f64mem:$src), "divsd {$src, $dst|$dst, $src}">, XD; -def DIVSDrr : I<0x5E, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def DIVSDrr : I<0x5E, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src), "divsd {$src, $dst|$dst, $src}">, XD; -def SUBSSrm : I<0x5C, MRMSrcMem, (ops RXMM:$dst, RXMM:$src1, f32mem:$src), +def SUBSSrm : I<0x5C, MRMSrcMem, (ops V4F4:$dst, V4F4:$src1, f32mem:$src), "subss {$src, $dst|$dst, $src}">, XS; -def SUBSSrr : I<0x5C, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def SUBSSrr : I<0x5C, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src), "subss {$src, $dst|$dst, $src}">, XS; -def SUBSDrm : I<0x5C, MRMSrcMem, (ops RXMM:$dst, RXMM:$src1, f64mem:$src), +def SUBSDrm : I<0x5C, MRMSrcMem, (ops V2F8:$dst, V2F8:$src1, f64mem:$src), "subsd {$src, $dst|$dst, $src}">, XD; -def SUBSDrr : I<0x5C, MRMSrcReg, (ops RXMM:$dst, RXMM:$src1, RXMM:$src), +def SUBSDrr : I<0x5C, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src), "subsd {$src, $dst|$dst, $src}">, XD; def CMPSSrr : I<0xC2, MRMSrcReg, - (ops RXMM:$dst, RXMM:$src1, RXMM:$src, SSECC:$cc), + (ops V4F4:$dst, V4F4:$src1, V4F4:$src, SSECC:$cc), "cmp${cc}ss {$src, $dst|$dst, $src}">, XS; def CMPSSrm : I<0xC2, MRMSrcMem, - (ops RXMM:$dst, RXMM:$src1, f32mem:$src, SSECC:$cc), + (ops V4F4:$dst, V4F4:$src1, f32mem:$src, SSECC:$cc), "cmp${cc}ss {$src, $dst|$dst, $src}">, XS; def CMPSDrr : I<0xC2, MRMSrcReg, - (ops RXMM:$dst, RXMM:$src1, RXMM:$src, SSECC:$cc), + (ops V2F8:$dst, V2F8:$src1, V2F8:$src, SSECC:$cc), "cmp${cc}sd {$src, $dst|$dst, $src}">, XD; def CMPSDrm : I<0xC2, MRMSrcMem, - (ops RXMM:$dst, RXMM:$src1, f64mem:$src, SSECC:$cc), + (ops V2F8:$dst, V2F8:$src1, f64mem:$src, SSECC:$cc), "cmp${cc}sd {$src, $dst|$dst, $src}">, XD; } Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.111 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.112 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.111 Fri Sep 30 12:12:38 2005 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Fri Oct 14 17:06:00 2005 @@ -57,7 +57,9 @@ Opc = X86::MOV16mr; } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { Opc = X86::FST64m; - } else if (RC == &X86::RXMMRegClass) { + } else if (RC == &X86::V4F4RegClass) { + Opc = X86::MOVSSmr; + } else if (RC == &X86::V2F8RegClass) { Opc = X86::MOVSDmr; } else { assert(0 && "Unknown regclass"); @@ -79,7 +81,9 @@ Opc = X86::MOV16rm; } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { Opc = X86::FLD64m; - } else if (RC == &X86::RXMMRegClass) { + } else if (RC == &X86::V4F4RegClass) { + Opc = X86::MOVSSrm; + } else if (RC == &X86::V2F8RegClass) { Opc = X86::MOVSDrm; } else { assert(0 && "Unknown regclass"); @@ -101,8 +105,10 @@ Opc = X86::MOV16rr; } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { Opc = X86::FpMOV; - } else if (RC == &X86::RXMMRegClass) { - Opc = X86::MOVAPDrr; + } else if (RC == &X86::V4F4RegClass) { + Opc = X86::MOVSSrr; + } else if (RC == &X86::V2F8RegClass) { + Opc = X86::MOVSDrr; } else { assert(0 && "Unknown regclass"); abort(); @@ -119,7 +125,7 @@ case X86::MOV32rm: case X86::FLD64m: case X86::FLD80m: - case X86::MOVAPDrm: + case X86::MOVSSrm: case X86::MOVSDrm: if (MI->getOperand(1).isFrameIndex() && MI->getOperand(2).isImmediate() && MI->getOperand(3).isRegister() && MI->getOperand(4).isImmediate() && Index: llvm/lib/Target/X86/X86RegisterInfo.td diff -u llvm/lib/Target/X86/X86RegisterInfo.td:1.21 llvm/lib/Target/X86/X86RegisterInfo.td:1.22 --- llvm/lib/Target/X86/X86RegisterInfo.td:1.21 Fri Aug 19 14:13:20 2005 +++ llvm/lib/Target/X86/X86RegisterInfo.td Fri Oct 14 17:06:00 2005 @@ -104,10 +104,11 @@ }]; } -// FIXME: These registers can contain both integer and fp values. We should -// figure out the right way to deal with that. For now, since they'll be used -// for scalar FP, they are being declared f64 -def RXMM : RegisterClass<"X86", f64, 32, +// V4F4, the 4 x f32 class, and V2F8, the 2 x f64 class, which we will use for +// Scalar SSE2 floating point support. +def V4F4 : RegisterClass<"X86", f32, 32, + [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; +def V2F8 : RegisterClass<"X86", f64, 64, [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; // FIXME: This sets up the floating point register files as though they are f64 From lattner at cs.uiuc.edu Fri Oct 14 17:44:24 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 17:44:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PPC32InstrInfo.h PowerPCAsmPrinter.cpp PowerPCBranchSelector.cpp PowerPCInstrFormats.td PowerPCInstrInfo.h Message-ID: <200510142244.RAA05558@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.183 -> 1.184 PPC32InstrInfo.h updated: 1.3 -> 1.4 PowerPCAsmPrinter.cpp updated: 1.92 -> 1.93 PowerPCBranchSelector.cpp updated: 1.15 -> 1.16 PowerPCInstrFormats.td updated: 1.51 -> 1.52 PowerPCInstrInfo.h (r1.9) removed --- Log message: Nuke PowerPCInstrFormats.h, its contents are dead. Remove the definitions from the .td file that correspond to it --- Diffs of the changes: (+11 -32) PPC32ISelPattern.cpp | 2 +- PPC32InstrInfo.h | 5 +++-- PowerPCAsmPrinter.cpp | 7 +++++++ PowerPCBranchSelector.cpp | 1 - PowerPCInstrFormats.td | 28 ---------------------------- 5 files changed, 11 insertions(+), 32 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.183 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.184 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.183 Sun Oct 2 02:07:49 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Fri Oct 14 17:44:13 2005 @@ -15,7 +15,7 @@ #include "PowerPC.h" #include "PowerPCInstrBuilder.h" -#include "PowerPCInstrInfo.h" +#include "PPC32InstrInfo.h" #include "PPC32TargetMachine.h" #include "PPC32ISelLowering.h" #include "llvm/Constants.h" Index: llvm/lib/Target/PowerPC/PPC32InstrInfo.h diff -u llvm/lib/Target/PowerPC/PPC32InstrInfo.h:1.3 llvm/lib/Target/PowerPC/PPC32InstrInfo.h:1.4 --- llvm/lib/Target/PowerPC/PPC32InstrInfo.h:1.3 Fri Sep 9 13:17:41 2005 +++ llvm/lib/Target/PowerPC/PPC32InstrInfo.h Fri Oct 14 17:44:13 2005 @@ -14,11 +14,12 @@ #ifndef POWERPC32_INSTRUCTIONINFO_H #define POWERPC32_INSTRUCTIONINFO_H -#include "PowerPCInstrInfo.h" +#include "PowerPC.h" +#include "llvm/Target/TargetInstrInfo.h" #include "PPC32RegisterInfo.h" namespace llvm { - + class PPC32InstrInfo : public TargetInstrInfo { const PPC32RegisterInfo RI; public: Index: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.92 llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.93 --- llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.92 Mon Oct 3 02:08:36 2005 +++ llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Fri Oct 14 17:44:13 2005 @@ -342,6 +342,13 @@ /// void PowerPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { ++EmittedInsts; + +/// NOTE: THIS SHOULD NEVER BE CHECKED IN. STAY LOCAL IN CHRIS'S TREE. + if (0 && MI->getOpcode() == PPC::OR) + assert((MI->getOperand(0).getReg() != MI->getOperand(1).getReg() || + MI->getOperand(2).getReg() != MI->getOperand(1).getReg()) && + "noop copy emitted!"); + // Check for slwi/srwi mnemonics. if (MI->getOpcode() == PPC::RLWINM) { bool FoundMnemonic = false; Index: llvm/lib/Target/PowerPC/PowerPCBranchSelector.cpp diff -u llvm/lib/Target/PowerPC/PowerPCBranchSelector.cpp:1.15 llvm/lib/Target/PowerPC/PowerPCBranchSelector.cpp:1.16 --- llvm/lib/Target/PowerPC/PowerPCBranchSelector.cpp:1.15 Fri Sep 30 20:34:18 2005 +++ llvm/lib/Target/PowerPC/PowerPCBranchSelector.cpp Fri Oct 14 17:44:13 2005 @@ -18,7 +18,6 @@ #define DEBUG_TYPE "bsel" #include "PowerPC.h" #include "PowerPCInstrBuilder.h" -#include "PowerPCInstrInfo.h" #include "PPC32InstrInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Support/Debug.h" Index: llvm/lib/Target/PowerPC/PowerPCInstrFormats.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.51 llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.52 --- llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.51 Thu Sep 29 18:34:24 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrFormats.td Fri Oct 14 17:44:13 2005 @@ -10,34 +10,6 @@ // //===----------------------------------------------------------------------===// -class Format val> { - bits<5> Value = val; -} - -def Pseudo: Format<0>; -def Gpr : Format<1>; -def Gpr0 : Format<2>; -def Simm16 : Format<3>; -def PCRelimm24 : Format<5>; -def Imm24 : Format<6>; -def Imm5 : Format<7>; -def PCRelimm14 : Format<8>; -def Imm14 : Format<9>; -def Imm2 : Format<10>; -def Crf : Format<11>; -def Imm3 : Format<12>; -def Imm1 : Format<13>; -def Fpr : Format<14>; -def Imm4 : Format<15>; -def Imm8 : Format<16>; -def Disimm16 : Format<17>; -def Disimm14 : Format<18>; -def Spr : Format<19>; -def Sgr : Format<20>; -def Imm15 : Format<21>; -def Vpr : Format<22>; -def Imm6 : Format<23>; - //===----------------------------------------------------------------------===// // // PowerPC instruction formats From lattner at cs.uiuc.edu Fri Oct 14 17:48:36 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 17:48:36 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Message-ID: <200510142248.RAA05648@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCAsmPrinter.cpp updated: 1.93 -> 1.94 --- Log message: Like the comment says... --- Diffs of the changes: (+0 -6) PowerPCAsmPrinter.cpp | 6 ------ 1 files changed, 6 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.93 llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.94 --- llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.93 Fri Oct 14 17:44:13 2005 +++ llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Fri Oct 14 17:48:24 2005 @@ -343,12 +343,6 @@ void PowerPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { ++EmittedInsts; -/// NOTE: THIS SHOULD NEVER BE CHECKED IN. STAY LOCAL IN CHRIS'S TREE. - if (0 && MI->getOpcode() == PPC::OR) - assert((MI->getOperand(0).getReg() != MI->getOperand(1).getReg() || - MI->getOperand(2).getReg() != MI->getOperand(1).getReg()) && - "noop copy emitted!"); - // Check for slwi/srwi mnemonics. if (MI->getOpcode() == PPC::RLWINM) { bool FoundMnemonic = false; From lattner at cs.uiuc.edu Fri Oct 14 18:37:46 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 18:37:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC.td Makefile PPC32RegisterInfo.h PPCAsmPrinter.cpp PPCCodeEmitter.cpp PPCISelDAGToDAG.cpp PPCInstrInfo.cpp PPCRegisterInfo.cpp PowerPC.h Message-ID: <200510142337.SAA05978@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC.td added (r1.1) Makefile updated: 1.19 -> 1.20 PPC32RegisterInfo.h updated: 1.6 -> 1.7 PPCAsmPrinter.cpp updated: 1.94 -> 1.95 PPCCodeEmitter.cpp updated: 1.35 -> 1.36 PPCISelDAGToDAG.cpp updated: 1.100 -> 1.101 PPCInstrInfo.cpp updated: 1.7 -> 1.8 PPCRegisterInfo.cpp updated: 1.29 -> 1.30 PowerPC.h updated: 1.21 -> 1.22 --- Log message: Eliminate PowerPC.td and PPC32.td, consolidating them into PPC.td --- Diffs of the changes: (+70 -32) Makefile | 10 +++++----- PPC.td | 38 ++++++++++++++++++++++++++++++++++++++ PPC32RegisterInfo.h | 4 ++-- PPCAsmPrinter.cpp | 20 ++++++++++---------- PPCCodeEmitter.cpp | 16 ++++++++-------- PPCISelDAGToDAG.cpp | 2 +- PPCInstrInfo.cpp | 4 ++-- PPCRegisterInfo.cpp | 4 ++-- PowerPC.h | 4 ++-- 9 files changed, 70 insertions(+), 32 deletions(-) Index: llvm/lib/Target/PowerPC/PPC.td diff -c /dev/null llvm/lib/Target/PowerPC/PPC.td:1.1 *** /dev/null Fri Oct 14 18:37:45 2005 --- llvm/lib/Target/PowerPC/PPC.td Fri Oct 14 18:37:35 2005 *************** *** 0 **** --- 1,38 ---- + //===- PPC.td - Describe the PowerPC Target Machine --------*- tablegen -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This is the top level entry point for the PowerPC target. + // + //===----------------------------------------------------------------------===// + + // Get the target-independent interfaces which we are implementing. + // + include "../Target.td" + + //===----------------------------------------------------------------------===// + // Register File Description + //===----------------------------------------------------------------------===// + + include "PowerPCRegisterInfo.td" + include "PowerPCInstrInfo.td" + + def PPC : Target { + // Pointers on PPC are 32-bits in size. + let PointerType = i32; + + // According to the Mach-O Runtime ABI, these regs are nonvolatile across + // calls + let CalleeSavedRegisters = [R1, R13, R14, R15, R16, R17, R18, R19, + R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, F14, F15, + F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, + F30, F31, CR2, CR3, CR4, LR]; + + // Pull in Instruction Info: + let InstructionSet = PowerPCInstrInfo; + } Index: llvm/lib/Target/PowerPC/Makefile diff -u llvm/lib/Target/PowerPC/Makefile:1.19 llvm/lib/Target/PowerPC/Makefile:1.20 --- llvm/lib/Target/PowerPC/Makefile:1.19 Fri Sep 2 20:15:41 2005 +++ llvm/lib/Target/PowerPC/Makefile Fri Oct 14 18:37:35 2005 @@ -8,12 +8,12 @@ ##===----------------------------------------------------------------------===## LEVEL = ../../.. LIBRARYNAME = LLVMPowerPC -TARGET = PowerPC PPC32 +TARGET = PPC # Make sure that tblgen is run, first thing. -BUILT_SOURCES = PowerPCGenInstrNames.inc PowerPCGenRegisterNames.inc \ - PowerPCGenAsmWriter.inc PPC32GenCodeEmitter.inc \ - PPC32GenRegisterInfo.h.inc PPC32GenRegisterInfo.inc \ - PPC32GenInstrInfo.inc PPC32GenDAGISel.inc +BUILT_SOURCES = PPCGenInstrNames.inc PPCGenRegisterNames.inc \ + PPCGenAsmWriter.inc PPCGenCodeEmitter.inc \ + PPCGenRegisterInfo.h.inc PPCGenRegisterInfo.inc \ + PPCGenInstrInfo.inc PPCGenDAGISel.inc include $(LEVEL)/Makefile.common Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.h diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.h:1.6 llvm/lib/Target/PowerPC/PPC32RegisterInfo.h:1.7 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.h:1.6 Thu Sep 29 20:30:55 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.h Fri Oct 14 18:37:35 2005 @@ -15,14 +15,14 @@ #define POWERPC32_REGISTERINFO_H #include "PowerPC.h" -#include "PPC32GenRegisterInfo.h.inc" +#include "PPCGenRegisterInfo.h.inc" #include namespace llvm { class Type; -class PPC32RegisterInfo : public PPC32GenRegisterInfo { +class PPC32RegisterInfo : public PPCGenRegisterInfo { std::map ImmToIdxMap; public: PPC32RegisterInfo(); Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.94 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.95 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.94 Fri Oct 14 17:48:24 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Fri Oct 14 18:37:35 2005 @@ -1,4 +1,4 @@ -//===-- PowerPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --===// +//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --===// // // The LLVM Compiler Infrastructure // @@ -43,10 +43,10 @@ namespace { Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); - struct PowerPCAsmPrinter : public AsmPrinter { + struct PPCAsmPrinter : public AsmPrinter { std::set FnStubs, GVStubs, LinkOnceStubs; - PowerPCAsmPrinter(std::ostream &O, TargetMachine &TM) + PPCAsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM), LabelNumber(0) {} /// Unique incrementer for label values for referencing Global values. @@ -175,10 +175,10 @@ /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS /// X /// - struct DarwinAsmPrinter : public PowerPCAsmPrinter { + struct DarwinAsmPrinter : public PPCAsmPrinter { DarwinAsmPrinter(std::ostream &O, TargetMachine &TM) - : PowerPCAsmPrinter(O, TM) { + : PPCAsmPrinter(O, TM) { CommentString = ";"; GlobalPrefix = "_"; ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. @@ -198,13 +198,13 @@ /// AIXAsmPrinter - PowerPC assembly printer, customized for AIX /// - struct AIXAsmPrinter : public PowerPCAsmPrinter { + struct AIXAsmPrinter : public PPCAsmPrinter { /// Map for labels corresponding to global variables /// std::map GVToLabelMap; AIXAsmPrinter(std::ostream &O, TargetMachine &TM) - : PowerPCAsmPrinter(O, TM) { + : PPCAsmPrinter(O, TM) { CommentString = "#"; GlobalPrefix = "_"; ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. @@ -252,9 +252,9 @@ } // Include the auto-generated portion of the assembly writer -#include "PowerPCGenAsmWriter.inc" +#include "PPCGenAsmWriter.inc" -void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { +void PPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { const MRegisterInfo &RI = *TM.getRegisterInfo(); int new_symbol; @@ -340,7 +340,7 @@ /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to /// the current output stream. /// -void PowerPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { +void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { ++EmittedInsts; // Check for slwi/srwi mnemonics. Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.35 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.36 --- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.35 Fri Sep 30 20:35:02 2005 +++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Fri Oct 14 18:37:35 2005 @@ -1,4 +1,4 @@ -//===-- PPC32CodeEmitter.cpp - JIT Code Emitter for PowerPC32 -----*- C++ -*-=// +//===-- PPCCodeEmitter.cpp - JIT Code Emitter for PowerPC32 -----*- C++ -*-=// // // The LLVM Compiler Infrastructure // @@ -24,7 +24,7 @@ using namespace llvm; namespace { - class PPC32CodeEmitter : public MachineFunctionPass { + class PPCCodeEmitter : public MachineFunctionPass { TargetMachine &TM; MachineCodeEmitter &MCE; @@ -38,7 +38,7 @@ int getMachineOpValue(MachineInstr &MI, MachineOperand &MO); public: - PPC32CodeEmitter(TargetMachine &T, MachineCodeEmitter &M) + PPCCodeEmitter(TargetMachine &T, MachineCodeEmitter &M) : TM(T), MCE(M) {} const char *getPassName() const { return "PowerPC Machine Code Emitter"; } @@ -76,13 +76,13 @@ bool PPC32TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM, MachineCodeEmitter &MCE) { // Machine code emitter pass for PowerPC - PM.add(new PPC32CodeEmitter(*this, MCE)); + PM.add(new PPCCodeEmitter(*this, MCE)); // Delete machine code for this function after emitting it PM.add(createMachineCodeDeleter()); return false; } -bool PPC32CodeEmitter::runOnMachineFunction(MachineFunction &MF) { +bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { MCE.startFunction(MF); MCE.emitConstantPool(MF.getConstantPool()); for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) @@ -114,7 +114,7 @@ return false; } -void PPC32CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { +void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { assert(!PICEnabled && "CodeEmitter does not support PIC!"); BBLocations[&MBB] = MCE.getCurrentPCValue(); for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){ @@ -175,7 +175,7 @@ } } -int PPC32CodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { +int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { int rv = 0; // Return value; defaults to 0 for unhandled cases // or things that get fixed up later by the JIT. @@ -260,5 +260,5 @@ return rv; } -#include "PPC32GenCodeEmitter.inc" +#include "PPCGenCodeEmitter.inc" Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.100 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.101 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.100 Fri Oct 14 01:26:29 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Fri Oct 14 18:37:35 2005 @@ -90,7 +90,7 @@ } // Include the pieces autogenerated from the target description. -#include "PPC32GenDAGISel.inc" +#include "PPCGenDAGISel.inc" private: SDOperand SelectDYNAMIC_STACKALLOC(SDOperand Op); Index: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.7 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.8 --- llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.7 Fri Oct 7 00:00:52 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.cpp Fri Oct 14 18:37:35 2005 @@ -12,14 +12,14 @@ //===----------------------------------------------------------------------===// #include "PPC32InstrInfo.h" -#include "PPC32GenInstrInfo.inc" +#include "PPCGenInstrInfo.inc" #include "PowerPC.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include using namespace llvm; PPC32InstrInfo::PPC32InstrInfo() - : TargetInstrInfo(PPC32Insts, sizeof(PPC32Insts)/sizeof(PPC32Insts[0])) {} + : TargetInstrInfo(PPCInsts, sizeof(PPCInsts)/sizeof(PPCInsts[0])) {} bool PPC32InstrInfo::isMoveInstr(const MachineInstr& MI, unsigned& sourceReg, Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.29 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.30 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.29 Sat Oct 1 18:02:40 2005 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Fri Oct 14 18:37:35 2005 @@ -32,7 +32,7 @@ using namespace llvm; PPC32RegisterInfo::PPC32RegisterInfo() - : PPC32GenRegisterInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP) { + : PPCGenRegisterInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP) { ImmToIdxMap[PPC::LD] = PPC::LDX; ImmToIdxMap[PPC::STD] = PPC::STDX; ImmToIdxMap[PPC::LBZ] = PPC::LBZX; ImmToIdxMap[PPC::STB] = PPC::STBX; ImmToIdxMap[PPC::LHZ] = PPC::LHZX; ImmToIdxMap[PPC::LHA] = PPC::LHAX; @@ -342,5 +342,5 @@ } } -#include "PPC32GenRegisterInfo.inc" +#include "PPCGenRegisterInfo.inc" Index: llvm/lib/Target/PowerPC/PowerPC.h diff -u llvm/lib/Target/PowerPC/PowerPC.h:1.21 llvm/lib/Target/PowerPC/PowerPC.h:1.22 --- llvm/lib/Target/PowerPC/PowerPC.h:1.21 Thu Aug 18 18:53:15 2005 +++ llvm/lib/Target/PowerPC/PowerPC.h Fri Oct 14 18:37:35 2005 @@ -42,10 +42,10 @@ // Defines symbolic names for PowerPC registers. This defines a mapping from // register name to register number. // -#include "PowerPCGenRegisterNames.inc" +#include "PPCGenRegisterNames.inc" // Defines symbolic names for the PowerPC instructions. // -#include "PowerPCGenInstrNames.inc" +#include "PPCGenInstrNames.inc" #endif From lattner at cs.uiuc.edu Fri Oct 14 18:39:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 18:39:04 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPC.td PPC32.td Message-ID: <200510142339.SAA06040@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPC.td (r1.14) removed PPC32.td (r1.5) removed --- Log message: These are dead --- Diffs of the changes: (+0 -0) 0 files changed From lattner at cs.uiuc.edu Fri Oct 14 18:40:51 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 18:40:51 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC.td PPCInstrInfo.td Message-ID: <200510142340.SAA06108@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC.td updated: 1.1 -> 1.2 PPCInstrInfo.td updated: 1.120 -> 1.121 --- Log message: Rename PowerPC*.td -> PPC*.td --- Diffs of the changes: (+4 -4) PPC.td | 4 ++-- PPCInstrInfo.td | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Target/PowerPC/PPC.td diff -u llvm/lib/Target/PowerPC/PPC.td:1.1 llvm/lib/Target/PowerPC/PPC.td:1.2 --- llvm/lib/Target/PowerPC/PPC.td:1.1 Fri Oct 14 18:37:35 2005 +++ llvm/lib/Target/PowerPC/PPC.td Fri Oct 14 18:40:39 2005 @@ -19,8 +19,8 @@ // Register File Description //===----------------------------------------------------------------------===// -include "PowerPCRegisterInfo.td" -include "PowerPCInstrInfo.td" +include "PPCRegisterInfo.td" +include "PPCInstrInfo.td" def PPC : Target { // Pointers on PPC are 32-bits in size. Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.120 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.121 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.120 Thu Oct 13 23:55:50 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Fri Oct 14 18:40:39 2005 @@ -1,4 +1,4 @@ -//===- PowerPCInstrInfo.td - The PowerPC Instruction Set -----*- tablegen -*-=// +//===- PPCInstrInfo.td - The PowerPC Instruction Set -------*- tablegen -*-===// // // The LLVM Compiler Infrastructure // @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -include "PowerPCInstrFormats.td" +include "PPCInstrFormats.td" //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Fri Oct 14 18:44:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 18:44:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32TargetMachine.h PPCAsmPrinter.cpp PPCTargetMachine.cpp PowerPCTargetMachine.h Message-ID: <200510142344.SAA06170@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32TargetMachine.h updated: 1.8 -> 1.9 PPCAsmPrinter.cpp updated: 1.95 -> 1.96 PPCTargetMachine.cpp updated: 1.69 -> 1.70 PowerPCTargetMachine.h (r1.15) removed --- Log message: Nuke the PowerPCTargetMachine.h header. Note that the PowerPCTargetMachine still should be merged into the PPC32TargetMachine class --- Diffs of the changes: (+24 -3) PPC32TargetMachine.h | 24 +++++++++++++++++++++++- PPCAsmPrinter.cpp | 2 +- PPCTargetMachine.cpp | 1 - 3 files changed, 24 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32TargetMachine.h diff -u llvm/lib/Target/PowerPC/PPC32TargetMachine.h:1.8 llvm/lib/Target/PowerPC/PPC32TargetMachine.h:1.9 --- llvm/lib/Target/PowerPC/PPC32TargetMachine.h:1.8 Thu Sep 1 16:38:20 2005 +++ llvm/lib/Target/PowerPC/PPC32TargetMachine.h Fri Oct 14 18:44:05 2005 @@ -14,15 +14,37 @@ #ifndef POWERPC32_TARGETMACHINE_H #define POWERPC32_TARGETMACHINE_H -#include "PowerPCTargetMachine.h" +#include "PowerPCFrameInfo.h" +#include "PowerPCSubtarget.h" #include "PPC32JITInfo.h" #include "PPC32InstrInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetFrameInfo.h" #include "llvm/PassManager.h" namespace llvm { class IntrinsicLowering; +class GlobalValue; +class IntrinsicLowering; +// FIXME: Merge into only subclass. +class PowerPCTargetMachine : public TargetMachine { + PowerPCFrameInfo FrameInfo; + PPCSubtarget Subtarget; +protected: + PowerPCTargetMachine(const std::string &name, IntrinsicLowering *IL, + const Module &M, const std::string &FS, + const TargetData &TD, + const PowerPCFrameInfo &TFI); +public: + virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } + virtual const TargetSubtarget *getSubtargetImpl() const{ return &Subtarget; } + + virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, + CodeGenFileType FileType); +}; + class PPC32TargetMachine : public PowerPCTargetMachine { PPC32InstrInfo InstrInfo; PPC32JITInfo JITInfo; Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.95 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.96 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.95 Fri Oct 14 18:37:35 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Fri Oct 14 18:44:05 2005 @@ -18,7 +18,7 @@ #define DEBUG_TYPE "asmprinter" #include "PowerPC.h" -#include "PowerPCTargetMachine.h" +#include "PPC32TargetMachine.h" #include "PowerPCSubtarget.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" Index: llvm/lib/Target/PowerPC/PPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.69 llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.70 --- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.69 Thu Sep 29 12:31:03 2005 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.cpp Fri Oct 14 18:44:05 2005 @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "PowerPC.h" -#include "PowerPCTargetMachine.h" #include "PowerPCFrameInfo.h" #include "PPC32TargetMachine.h" #include "PPC32JITInfo.h" From lattner at cs.uiuc.edu Fri Oct 14 18:45:54 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 18:45:54 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCBranchSelector.cpp PPCISelPattern.cpp PPCRegisterInfo.cpp Message-ID: <200510142345.SAA06265@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCBranchSelector.cpp updated: 1.16 -> 1.17 PPCISelPattern.cpp updated: 1.184 -> 1.185 PPCRegisterInfo.cpp updated: 1.30 -> 1.31 --- Log message: Rename PowerPCInstrBuilder.h -> PPC* --- Diffs of the changes: (+3 -3) PPCBranchSelector.cpp | 2 +- PPCISelPattern.cpp | 2 +- PPCRegisterInfo.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPCBranchSelector.cpp diff -u llvm/lib/Target/PowerPC/PPCBranchSelector.cpp:1.16 llvm/lib/Target/PowerPC/PPCBranchSelector.cpp:1.17 --- llvm/lib/Target/PowerPC/PPCBranchSelector.cpp:1.16 Fri Oct 14 17:44:13 2005 +++ llvm/lib/Target/PowerPC/PPCBranchSelector.cpp Fri Oct 14 18:45:43 2005 @@ -17,7 +17,7 @@ #define DEBUG_TYPE "bsel" #include "PowerPC.h" -#include "PowerPCInstrBuilder.h" +#include "PPCInstrBuilder.h" #include "PPC32InstrInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Support/Debug.h" Index: llvm/lib/Target/PowerPC/PPCISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.184 llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.185 --- llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.184 Fri Oct 14 17:44:13 2005 +++ llvm/lib/Target/PowerPC/PPCISelPattern.cpp Fri Oct 14 18:45:43 2005 @@ -14,7 +14,7 @@ //===----------------------------------------------------------------------===// #include "PowerPC.h" -#include "PowerPCInstrBuilder.h" +#include "PPCInstrBuilder.h" #include "PPC32InstrInfo.h" #include "PPC32TargetMachine.h" #include "PPC32ISelLowering.h" Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.30 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.31 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.30 Fri Oct 14 18:37:35 2005 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Fri Oct 14 18:45:43 2005 @@ -13,7 +13,7 @@ #define DEBUG_TYPE "reginfo" #include "PowerPC.h" -#include "PowerPCInstrBuilder.h" +#include "PPCInstrBuilder.h" #include "PPC32RegisterInfo.h" #include "llvm/Constants.h" #include "llvm/Type.h" From lattner at cs.uiuc.edu Fri Oct 14 18:51:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 18:51:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelLowering.h PPC32InstrInfo.h PPC32JITInfo.h PPC32RegisterInfo.h PPC32TargetMachine.h PPCAsmPrinter.cpp PPCBranchSelector.cpp PPCCodeEmitter.cpp PPCFrameInfo.h PPCISelDAGToDAG.cpp PPCISelPattern.cpp PPCInstrInfo.cpp PPCRegisterInfo.cpp PPCSubtarget.cpp PPCTargetMachine.cpp Message-ID: <200510142351.SAA06474@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelLowering.h updated: 1.6 -> 1.7 PPC32InstrInfo.h updated: 1.4 -> 1.5 PPC32JITInfo.h updated: 1.6 -> 1.7 PPC32RegisterInfo.h updated: 1.7 -> 1.8 PPC32TargetMachine.h updated: 1.9 -> 1.10 PPCAsmPrinter.cpp updated: 1.96 -> 1.97 PPCBranchSelector.cpp updated: 1.17 -> 1.18 PPCCodeEmitter.cpp updated: 1.36 -> 1.37 PPCFrameInfo.h updated: 1.7 -> 1.8 PPCISelDAGToDAG.cpp updated: 1.101 -> 1.102 PPCISelPattern.cpp updated: 1.185 -> 1.186 PPCInstrInfo.cpp updated: 1.8 -> 1.9 PPCRegisterInfo.cpp updated: 1.31 -> 1.32 PPCSubtarget.cpp updated: 1.8 -> 1.9 PPCTargetMachine.cpp updated: 1.70 -> 1.71 --- Log message: Rename PowerPC*.h to PPC*.h --- Diffs of the changes: (+19 -19) PPC32ISelLowering.h | 2 +- PPC32InstrInfo.h | 2 +- PPC32JITInfo.h | 2 +- PPC32RegisterInfo.h | 2 +- PPC32TargetMachine.h | 4 ++-- PPCAsmPrinter.cpp | 4 ++-- PPCBranchSelector.cpp | 2 +- PPCCodeEmitter.cpp | 2 +- PPCFrameInfo.h | 2 +- PPCISelDAGToDAG.cpp | 2 +- PPCISelPattern.cpp | 2 +- PPCInstrInfo.cpp | 2 +- PPCRegisterInfo.cpp | 2 +- PPCSubtarget.cpp | 4 ++-- PPCTargetMachine.cpp | 4 ++-- 15 files changed, 19 insertions(+), 19 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.h diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.h:1.6 llvm/lib/Target/PowerPC/PPC32ISelLowering.h:1.7 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.h:1.6 Tue Sep 6 17:03:27 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.h Fri Oct 14 18:51:18 2005 @@ -17,7 +17,7 @@ #include "llvm/Target/TargetLowering.h" #include "llvm/CodeGen/SelectionDAG.h" -#include "PowerPC.h" +#include "PPC.h" namespace llvm { namespace PPCISD { Index: llvm/lib/Target/PowerPC/PPC32InstrInfo.h diff -u llvm/lib/Target/PowerPC/PPC32InstrInfo.h:1.4 llvm/lib/Target/PowerPC/PPC32InstrInfo.h:1.5 --- llvm/lib/Target/PowerPC/PPC32InstrInfo.h:1.4 Fri Oct 14 17:44:13 2005 +++ llvm/lib/Target/PowerPC/PPC32InstrInfo.h Fri Oct 14 18:51:18 2005 @@ -14,7 +14,7 @@ #ifndef POWERPC32_INSTRUCTIONINFO_H #define POWERPC32_INSTRUCTIONINFO_H -#include "PowerPC.h" +#include "PPC.h" #include "llvm/Target/TargetInstrInfo.h" #include "PPC32RegisterInfo.h" Index: llvm/lib/Target/PowerPC/PPC32JITInfo.h diff -u llvm/lib/Target/PowerPC/PPC32JITInfo.h:1.6 llvm/lib/Target/PowerPC/PPC32JITInfo.h:1.7 --- llvm/lib/Target/PowerPC/PPC32JITInfo.h:1.6 Fri Jul 22 15:49:37 2005 +++ llvm/lib/Target/PowerPC/PPC32JITInfo.h Fri Oct 14 18:51:18 2005 @@ -14,7 +14,7 @@ #ifndef POWERPC_DARWIN_JITINFO_H #define POWERPC_DARWIN_JITINFO_H -#include "PowerPCJITInfo.h" +#include "PPCJITInfo.h" namespace llvm { class TargetMachine; Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.h diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.h:1.7 llvm/lib/Target/PowerPC/PPC32RegisterInfo.h:1.8 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.h:1.7 Fri Oct 14 18:37:35 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.h Fri Oct 14 18:51:18 2005 @@ -14,7 +14,7 @@ #ifndef POWERPC32_REGISTERINFO_H #define POWERPC32_REGISTERINFO_H -#include "PowerPC.h" +#include "PPC.h" #include "PPCGenRegisterInfo.h.inc" #include Index: llvm/lib/Target/PowerPC/PPC32TargetMachine.h diff -u llvm/lib/Target/PowerPC/PPC32TargetMachine.h:1.9 llvm/lib/Target/PowerPC/PPC32TargetMachine.h:1.10 --- llvm/lib/Target/PowerPC/PPC32TargetMachine.h:1.9 Fri Oct 14 18:44:05 2005 +++ llvm/lib/Target/PowerPC/PPC32TargetMachine.h Fri Oct 14 18:51:18 2005 @@ -14,8 +14,8 @@ #ifndef POWERPC32_TARGETMACHINE_H #define POWERPC32_TARGETMACHINE_H -#include "PowerPCFrameInfo.h" -#include "PowerPCSubtarget.h" +#include "PPCFrameInfo.h" +#include "PPCSubtarget.h" #include "PPC32JITInfo.h" #include "PPC32InstrInfo.h" #include "llvm/Target/TargetMachine.h" Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.96 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.97 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.96 Fri Oct 14 18:44:05 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Fri Oct 14 18:51:18 2005 @@ -17,9 +17,9 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "asmprinter" -#include "PowerPC.h" +#include "PPC.h" #include "PPC32TargetMachine.h" -#include "PowerPCSubtarget.h" +#include "PPCSubtarget.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" Index: llvm/lib/Target/PowerPC/PPCBranchSelector.cpp diff -u llvm/lib/Target/PowerPC/PPCBranchSelector.cpp:1.17 llvm/lib/Target/PowerPC/PPCBranchSelector.cpp:1.18 --- llvm/lib/Target/PowerPC/PPCBranchSelector.cpp:1.17 Fri Oct 14 18:45:43 2005 +++ llvm/lib/Target/PowerPC/PPCBranchSelector.cpp Fri Oct 14 18:51:18 2005 @@ -16,7 +16,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "bsel" -#include "PowerPC.h" +#include "PPC.h" #include "PPCInstrBuilder.h" #include "PPC32InstrInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.36 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.37 --- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.36 Fri Oct 14 18:37:35 2005 +++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Fri Oct 14 18:51:18 2005 @@ -14,7 +14,7 @@ #include "PPC32TargetMachine.h" #include "PPC32Relocations.h" -#include "PowerPC.h" +#include "PPC.h" #include "llvm/Module.h" #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineFunctionPass.h" Index: llvm/lib/Target/PowerPC/PPCFrameInfo.h diff -u llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.7 llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.8 --- llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.7 Thu Apr 21 18:20:02 2005 +++ llvm/lib/Target/PowerPC/PPCFrameInfo.h Fri Oct 14 18:51:18 2005 @@ -13,7 +13,7 @@ #ifndef POWERPC_FRAMEINFO_H #define POWERPC_FRAMEINFO_H -#include "PowerPC.h" +#include "PPC.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetMachine.h" Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.101 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.102 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.101 Fri Oct 14 18:37:35 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Fri Oct 14 18:51:18 2005 @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "PowerPC.h" +#include "PPC.h" #include "PPC32TargetMachine.h" #include "PPC32ISelLowering.h" #include "llvm/CodeGen/MachineInstrBuilder.h" Index: llvm/lib/Target/PowerPC/PPCISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.185 llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.186 --- llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.185 Fri Oct 14 18:45:43 2005 +++ llvm/lib/Target/PowerPC/PPCISelPattern.cpp Fri Oct 14 18:51:18 2005 @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "PowerPC.h" +#include "PPC.h" #include "PPCInstrBuilder.h" #include "PPC32InstrInfo.h" #include "PPC32TargetMachine.h" Index: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.8 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.9 --- llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.8 Fri Oct 14 18:37:35 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.cpp Fri Oct 14 18:51:18 2005 @@ -13,7 +13,7 @@ #include "PPC32InstrInfo.h" #include "PPCGenInstrInfo.inc" -#include "PowerPC.h" +#include "PPC.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include using namespace llvm; Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.31 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.32 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.31 Fri Oct 14 18:45:43 2005 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Fri Oct 14 18:51:18 2005 @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "reginfo" -#include "PowerPC.h" +#include "PPC.h" #include "PPCInstrBuilder.h" #include "PPC32RegisterInfo.h" #include "llvm/Constants.h" Index: llvm/lib/Target/PowerPC/PPCSubtarget.cpp diff -u llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.8 llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.9 --- llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.8 Wed Sep 7 00:45:33 2005 +++ llvm/lib/Target/PowerPC/PPCSubtarget.cpp Fri Oct 14 18:51:18 2005 @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "PowerPCSubtarget.h" -#include "PowerPC.h" +#include "PPCSubtarget.h" +#include "PPC.h" #include "llvm/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Target/SubtargetFeature.h" Index: llvm/lib/Target/PowerPC/PPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.70 llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.71 --- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.70 Fri Oct 14 18:44:05 2005 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.cpp Fri Oct 14 18:51:18 2005 @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "PowerPC.h" -#include "PowerPCFrameInfo.h" +#include "PPC.h" +#include "PPCFrameInfo.h" #include "PPC32TargetMachine.h" #include "PPC32JITInfo.h" #include "llvm/Module.h" From lattner at cs.uiuc.edu Fri Oct 14 18:53:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 18:53:53 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32TargetMachine.h PPCJITInfo.cpp PPCJITInfo.h PPCTargetMachine.cpp PPC32JITInfo.h Message-ID: <200510142353.SAA06592@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32TargetMachine.h updated: 1.10 -> 1.11 PPCJITInfo.cpp updated: 1.14 -> 1.15 PPCJITInfo.h updated: 1.6 -> 1.7 PPCTargetMachine.cpp updated: 1.71 -> 1.72 PPC32JITInfo.h (r1.7) removed --- Log message: Merge PPCJITInfo.h and PPC32JITInfo.h. Note that the PowerPCJITInfo and PPC32JITInfo classes should be merged. --- Diffs of the changes: (+22 -4) PPC32TargetMachine.h | 2 +- PPCJITInfo.cpp | 2 +- PPCJITInfo.h | 20 +++++++++++++++++++- PPCTargetMachine.cpp | 2 +- 4 files changed, 22 insertions(+), 4 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32TargetMachine.h diff -u llvm/lib/Target/PowerPC/PPC32TargetMachine.h:1.10 llvm/lib/Target/PowerPC/PPC32TargetMachine.h:1.11 --- llvm/lib/Target/PowerPC/PPC32TargetMachine.h:1.10 Fri Oct 14 18:51:18 2005 +++ llvm/lib/Target/PowerPC/PPC32TargetMachine.h Fri Oct 14 18:53:41 2005 @@ -16,7 +16,7 @@ #include "PPCFrameInfo.h" #include "PPCSubtarget.h" -#include "PPC32JITInfo.h" +#include "PPCJITInfo.h" #include "PPC32InstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetFrameInfo.h" Index: llvm/lib/Target/PowerPC/PPCJITInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCJITInfo.cpp:1.14 llvm/lib/Target/PowerPC/PPCJITInfo.cpp:1.15 --- llvm/lib/Target/PowerPC/PPCJITInfo.cpp:1.14 Fri Jul 22 15:49:37 2005 +++ llvm/lib/Target/PowerPC/PPCJITInfo.cpp Fri Oct 14 18:53:41 2005 @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "jit" -#include "PPC32JITInfo.h" +#include "PPCJITInfo.h" #include "PPC32Relocations.h" #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/Config/alloca.h" Index: llvm/lib/Target/PowerPC/PPCJITInfo.h diff -u llvm/lib/Target/PowerPC/PPCJITInfo.h:1.6 llvm/lib/Target/PowerPC/PPCJITInfo.h:1.7 --- llvm/lib/Target/PowerPC/PPCJITInfo.h:1.6 Fri Jul 29 18:32:02 2005 +++ llvm/lib/Target/PowerPC/PPCJITInfo.h Fri Oct 14 18:53:41 2005 @@ -1,4 +1,4 @@ -//===- PowerPCJITInfo.h - PowerPC impl. of the JIT interface ----*- C++ -*-===// +//===- PPCJITInfo.h - PowerPC impl. of the JIT interface --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -19,6 +19,7 @@ namespace llvm { class TargetMachine; + // FIXME: Merge into one PPCJITInfo class. class PowerPCJITInfo : public TargetJITInfo { protected: TargetMachine &TM; @@ -31,6 +32,23 @@ /// virtual void addPassesToJITCompile(FunctionPassManager &PM); }; + + class PPC32JITInfo : public PowerPCJITInfo { + public: + PPC32JITInfo(TargetMachine &tm) : PowerPCJITInfo(tm) {} + + virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE); + virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn); + virtual void relocate(void *Function, MachineRelocation *MR, + unsigned NumRelocs, unsigned char* GOTBase); + + /// replaceMachineCodeForFunction - Make it so that calling the function + /// whose machine code is at OLD turns into a call to NEW, perhaps by + /// overwriting OLD with a branch to NEW. This is used for self-modifying + /// code. + /// + virtual void replaceMachineCodeForFunction(void *Old, void *New); + }; } #endif Index: llvm/lib/Target/PowerPC/PPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.71 llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.72 --- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.71 Fri Oct 14 18:51:18 2005 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.cpp Fri Oct 14 18:53:41 2005 @@ -14,7 +14,7 @@ #include "PPC.h" #include "PPCFrameInfo.h" #include "PPC32TargetMachine.h" -#include "PPC32JITInfo.h" +#include "PPCJITInfo.h" #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Analysis/Verifier.h" From lattner at cs.uiuc.edu Fri Oct 14 18:59:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 14 Oct 2005 18:59:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp PPCBranchSelector.cpp PPCCodeEmitter.cpp PPCISelDAGToDAG.cpp PPCISelLowering.cpp PPCISelPattern.cpp PPCInstrInfo.cpp PPCInstrInfo.h PPCJITInfo.cpp PPCRegisterInfo.cpp PPCTargetMachine.cpp PPCTargetMachine.h Message-ID: <200510142359.SAA06690@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.97 -> 1.98 PPCBranchSelector.cpp updated: 1.18 -> 1.19 PPCCodeEmitter.cpp updated: 1.37 -> 1.38 PPCISelDAGToDAG.cpp updated: 1.102 -> 1.103 PPCISelLowering.cpp updated: 1.29 -> 1.30 PPCISelPattern.cpp updated: 1.186 -> 1.187 PPCInstrInfo.cpp updated: 1.9 -> 1.10 PPCInstrInfo.h updated: 1.5 -> 1.6 PPCJITInfo.cpp updated: 1.15 -> 1.16 PPCRegisterInfo.cpp updated: 1.32 -> 1.33 PPCTargetMachine.cpp updated: 1.72 -> 1.73 PPCTargetMachine.h updated: 1.11 -> 1.12 --- Log message: Rename PPC32*.h to PPC*.h This completes the grand PPC file renaming --- Diffs of the changes: (+16 -17) PPCAsmPrinter.cpp | 2 +- PPCBranchSelector.cpp | 2 +- PPCCodeEmitter.cpp | 4 ++-- PPCISelDAGToDAG.cpp | 4 ++-- PPCISelLowering.cpp | 4 ++-- PPCISelPattern.cpp | 5 ++--- PPCInstrInfo.cpp | 2 +- PPCInstrInfo.h | 2 +- PPCJITInfo.cpp | 2 +- PPCRegisterInfo.cpp | 2 +- PPCTargetMachine.cpp | 2 +- PPCTargetMachine.h | 2 +- 12 files changed, 16 insertions(+), 17 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.97 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.98 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.97 Fri Oct 14 18:51:18 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Fri Oct 14 18:59:06 2005 @@ -18,7 +18,7 @@ #define DEBUG_TYPE "asmprinter" #include "PPC.h" -#include "PPC32TargetMachine.h" +#include "PPCTargetMachine.h" #include "PPCSubtarget.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" Index: llvm/lib/Target/PowerPC/PPCBranchSelector.cpp diff -u llvm/lib/Target/PowerPC/PPCBranchSelector.cpp:1.18 llvm/lib/Target/PowerPC/PPCBranchSelector.cpp:1.19 --- llvm/lib/Target/PowerPC/PPCBranchSelector.cpp:1.18 Fri Oct 14 18:51:18 2005 +++ llvm/lib/Target/PowerPC/PPCBranchSelector.cpp Fri Oct 14 18:59:06 2005 @@ -18,7 +18,7 @@ #define DEBUG_TYPE "bsel" #include "PPC.h" #include "PPCInstrBuilder.h" -#include "PPC32InstrInfo.h" +#include "PPCInstrInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Support/Debug.h" #include Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.37 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.38 --- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.37 Fri Oct 14 18:51:18 2005 +++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Fri Oct 14 18:59:06 2005 @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#include "PPC32TargetMachine.h" -#include "PPC32Relocations.h" +#include "PPCTargetMachine.h" +#include "PPCRelocations.h" #include "PPC.h" #include "llvm/Module.h" #include "llvm/CodeGen/MachineCodeEmitter.h" Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.102 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.103 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.102 Fri Oct 14 18:51:18 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Fri Oct 14 18:59:06 2005 @@ -13,8 +13,8 @@ //===----------------------------------------------------------------------===// #include "PPC.h" -#include "PPC32TargetMachine.h" -#include "PPC32ISelLowering.h" +#include "PPCTargetMachine.h" +#include "PPCISelLowering.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SSARegMap.h" Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.29 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.30 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.29 Sun Oct 2 01:37:13 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Fri Oct 14 18:59:06 2005 @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "PPC32ISelLowering.h" -#include "PPC32TargetMachine.h" +#include "PPCISelLowering.h" +#include "PPCTargetMachine.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" Index: llvm/lib/Target/PowerPC/PPCISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.186 llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.187 --- llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.186 Fri Oct 14 18:51:18 2005 +++ llvm/lib/Target/PowerPC/PPCISelPattern.cpp Fri Oct 14 18:59:06 2005 @@ -15,9 +15,8 @@ #include "PPC.h" #include "PPCInstrBuilder.h" -#include "PPC32InstrInfo.h" -#include "PPC32TargetMachine.h" -#include "PPC32ISelLowering.h" +#include "PPCTargetMachine.h" +#include "PPCISelLowering.h" #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/CodeGen/MachineConstantPool.h" Index: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.9 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.10 --- llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.9 Fri Oct 14 18:51:18 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.cpp Fri Oct 14 18:59:06 2005 @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "PPC32InstrInfo.h" +#include "PPCInstrInfo.h" #include "PPCGenInstrInfo.inc" #include "PPC.h" #include "llvm/CodeGen/MachineInstrBuilder.h" Index: llvm/lib/Target/PowerPC/PPCInstrInfo.h diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.5 llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.6 --- llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.5 Fri Oct 14 18:51:18 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.h Fri Oct 14 18:59:06 2005 @@ -16,7 +16,7 @@ #include "PPC.h" #include "llvm/Target/TargetInstrInfo.h" -#include "PPC32RegisterInfo.h" +#include "PPCRegisterInfo.h" namespace llvm { Index: llvm/lib/Target/PowerPC/PPCJITInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCJITInfo.cpp:1.15 llvm/lib/Target/PowerPC/PPCJITInfo.cpp:1.16 --- llvm/lib/Target/PowerPC/PPCJITInfo.cpp:1.15 Fri Oct 14 18:53:41 2005 +++ llvm/lib/Target/PowerPC/PPCJITInfo.cpp Fri Oct 14 18:59:06 2005 @@ -13,7 +13,7 @@ #define DEBUG_TYPE "jit" #include "PPCJITInfo.h" -#include "PPC32Relocations.h" +#include "PPCRelocations.h" #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/Config/alloca.h" #include Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.32 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.33 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.32 Fri Oct 14 18:51:18 2005 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Fri Oct 14 18:59:06 2005 @@ -14,7 +14,7 @@ #define DEBUG_TYPE "reginfo" #include "PPC.h" #include "PPCInstrBuilder.h" -#include "PPC32RegisterInfo.h" +#include "PPCRegisterInfo.h" #include "llvm/Constants.h" #include "llvm/Type.h" #include "llvm/CodeGen/ValueTypes.h" Index: llvm/lib/Target/PowerPC/PPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.72 llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.73 --- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.72 Fri Oct 14 18:53:41 2005 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.cpp Fri Oct 14 18:59:06 2005 @@ -13,7 +13,7 @@ #include "PPC.h" #include "PPCFrameInfo.h" -#include "PPC32TargetMachine.h" +#include "PPCTargetMachine.h" #include "PPCJITInfo.h" #include "llvm/Module.h" #include "llvm/PassManager.h" Index: llvm/lib/Target/PowerPC/PPCTargetMachine.h diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.11 llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.12 --- llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.11 Fri Oct 14 18:53:41 2005 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.h Fri Oct 14 18:59:06 2005 @@ -17,7 +17,7 @@ #include "PPCFrameInfo.h" #include "PPCSubtarget.h" #include "PPCJITInfo.h" -#include "PPC32InstrInfo.h" +#include "PPCInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/PassManager.h" From lattner at cs.uiuc.edu Sat Oct 15 14:04:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 15 Oct 2005 14:04:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelPattern.cpp Message-ID: <200510151904.OAA09671@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelPattern.cpp updated: 1.187 -> 1.188 --- Log message: remove broken SRA/rlwimi case --- Diffs of the changes: (+2 -11) PPCISelPattern.cpp | 13 ++----------- 1 files changed, 2 insertions(+), 11 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.187 llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.188 --- llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.187 Fri Oct 14 18:59:06 2005 +++ llvm/lib/Target/PowerPC/PPCISelPattern.cpp Sat Oct 15 14:04:48 2005 @@ -145,7 +145,7 @@ if (IsShiftMask) Mask = Mask << Shift; // determine which bits are made indeterminant by shift Indeterminant = ~(0xFFFFFFFFu << Shift); - } else if (Opcode == ISD::SRA || Opcode == ISD::SRL) { // shift rights + } else if (Opcode == ISD::SRL) { // shift rights // apply shift to mask if it comes first if (IsShiftMask) Mask = Mask >> Shift; // determine which bits are made indeterminant by shift @@ -1125,17 +1125,8 @@ case ISD::SRA: if (isIntImmediate(N.getOperand(1), Tmp2)) { - unsigned SH, MB, ME; - if (isOpcWithIntImmediate(N.getOperand(0), ISD::AND, Tmp3) && - isRotateAndMask(ISD::SRA, Tmp2, Tmp3, true, SH, MB, ME)) { - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(SH) - .addImm(MB).addImm(ME); - return Result; - } Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 &= 0x1F; - BuildMI(BB, PPC::SRAWI, 2, Result).addReg(Tmp1).addImm(Tmp2); + BuildMI(BB, PPC::SRAWI, 2, Result).addReg(Tmp1).addImm(Tmp2 & 0x1F); } else { Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = FoldIfWideZeroExtend(N.getOperand(1)); From lattner at cs.uiuc.edu Sat Oct 15 15:24:18 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 15 Oct 2005 15:24:18 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200510152024.PAA09913@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.199 -> 1.200 --- Log message: Use getExtLoad here instead of getNode, as extloads produce two values. This fixes a legalize failure on SPASS for itanium. --- Diffs of the changes: (+3 -2) LegalizeDAG.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.199 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.200 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.199 Thu Oct 13 20:12:21 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat Oct 15 15:24:07 2005 @@ -2355,8 +2355,9 @@ case ISD::EXTLOAD: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. - Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2, - Node->getOperand(2), Node->getOperand(3)); + Result = DAG.getExtLoad(Node->getOpcode(), NVT, Tmp1, Tmp2, + Node->getOperand(2), + cast(Node->getOperand(3))->getVT()); // Remember that we legalized the chain. AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); break; From lattner at cs.uiuc.edu Sat Oct 15 16:34:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 15 Oct 2005 16:34:32 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200510152134.QAA10249@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.56 -> 1.57 --- Log message: Implement the last major missing piece in the DAG isel generator: when emitting a pattern match, make sure to emit the (minimal number of) type checks that verify the pattern matches this specific instruction. This allows FMA32 patterns to not match double expressions for example. --- Diffs of the changes: (+47 -17) DAGISelEmitter.cpp | 64 ++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 47 insertions(+), 17 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.56 llvm/utils/TableGen/DAGISelEmitter.cpp:1.57 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.56 Fri Oct 14 01:25:00 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Sat Oct 15 16:34:21 2005 @@ -1634,6 +1634,31 @@ 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, + 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 << ".getValueType() != MVT::" + << getName(Pat->getType()) << ") goto P" << PatternNo << "Fail;\n"; + return true; + } else if (Pat->isLeaf()) { + return false; + } + + for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) + if (InsertOneTypeCheck(Pat->getChild(i), Other->getChild(i), + Prefix + utostr(i), PatternNo, OS)) + return true; + return false; +} + /// 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 /// succeeds. @@ -1670,25 +1695,30 @@ // TreePatternNode *Pat = Pattern.first->clone(); RemoveAllTypes(Pat); - bool MadeChange = true; - try { - while (MadeChange) - MadeChange = Pat->ApplyTypeConstraints(TP,true/*Ignore reg constraints*/); - } catch (...) { - assert(0 && "Error: could not find consistent types for something we" - " already decided was ok!"); - abort(); - } + + do { + // Resolve/propagate as many types as possible. + try { + bool MadeChange = true; + while (MadeChange) + MadeChange = Pat->ApplyTypeConstraints(TP,true/*Ignore reg constraints*/); + } catch (...) { + assert(0 && "Error: could not find consistent types for something we" + " already decided was ok!"); + abort(); + } - if (!Pat->ContainsUnresolvedType()) { - unsigned TmpNo = 0; - unsigned Res = CodeGenPatternResult(Pattern.second, TmpNo, VariableMap, OS); - - // Add the result to the map if it has multiple uses. - OS << " if (!N.Val->hasOneUse()) CodeGenMap[N] = Tmp" << Res << ";\n"; - OS << " return Tmp" << Res << ";\n"; - } + // 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, "N", PatternNo, OS)); + + unsigned TmpNo = 0; + unsigned Res = CodeGenPatternResult(Pattern.second, TmpNo, VariableMap, OS); + // Add the result to the map if it has multiple uses. + OS << " if (!N.Val->hasOneUse()) CodeGenMap[N] = Tmp" << Res << ";\n"; + OS << " return Tmp" << Res << ";\n"; delete Pat; OS << " }\n P" << PatternNo << "Fail:\n"; From lattner at cs.uiuc.edu Sat Oct 15 16:40:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 15 Oct 2005 16:40:23 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200510152140.QAA10349@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.103 -> 1.104 --- Log message: remove dead code --- Diffs of the changes: (+3 -8) PPCISelDAGToDAG.cpp | 11 +++-------- 1 files changed, 3 insertions(+), 8 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.103 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.104 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.103 Fri Oct 14 18:59:06 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Sat Oct 15 16:40:12 2005 @@ -233,7 +233,7 @@ if (IsShiftMask) Mask = Mask << Shift; // determine which bits are made indeterminant by shift Indeterminant = ~(0xFFFFFFFFu << Shift); - } else if (Opcode == ISD::SRA || Opcode == ISD::SRL) { + } else if (Opcode == ISD::SRL) { // apply shift right to mask if it comes first if (IsShiftMask) Mask = Mask >> Shift; // determine which bits are made indeterminant by shift @@ -1277,13 +1277,8 @@ return SDOperand(N, 0); } case ISD::SRA: { - unsigned Imm, SH, MB, ME; - if (0 &&isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) && - isRotateAndMask(N, Imm, true, SH, MB, ME)) - CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, - Select(N->getOperand(0).getOperand(0)), - getI32Imm(SH), getI32Imm(MB), getI32Imm(ME)); - else if (isIntImmediate(N->getOperand(1), Imm)) + unsigned Imm; + if (isIntImmediate(N->getOperand(1), Imm)) CurDAG->SelectNodeTo(N, PPC::SRAWI, MVT::i32, Select(N->getOperand(0)), getI32Imm(Imm)); else From lattner at cs.uiuc.edu Sat Oct 15 16:44:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 15 Oct 2005 16:44:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCInstrInfo.td Message-ID: <200510152144.QAA10411@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCInstrInfo.td updated: 1.121 -> 1.122 --- Log message: Add a pattern for FSQRTS --- Diffs of the changes: (+1 -1) PPCInstrInfo.td | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.121 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.122 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.121 Fri Oct 14 18:40:39 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Sat Oct 15 16:44:15 2005 @@ -430,7 +430,7 @@ [(set F8RC:$frD, (fsqrt F8RC:$frB))]>; def FSQRTS : XForm_26<59, 22, (ops F4RC:$frD, F4RC:$frB), "fsqrts $frD, $frB", - []>; + [(set F4RC:$frD, (fsqrt F4RC:$frB))]>; /// FMR is split into 3 versions, one for 4/8 byte FP, and one for extending. def FMRS : XForm_26<63, 72, (ops F4RC:$frD, F4RC:$frB), From lattner at cs.uiuc.edu Sat Oct 15 16:45:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 15 Oct 2005 16:45:08 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200510152145.QAA10474@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.104 -> 1.105 --- Log message: These instructions are now autogenerated --- Diffs of the changes: (+0 -34) PPCISelDAGToDAG.cpp | 34 ---------------------------------- 1 files changed, 34 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.104 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.105 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.104 Sat Oct 15 16:40:12 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Sat Oct 15 16:44:56 2005 @@ -1276,34 +1276,6 @@ Select(N->getOperand(1))); return SDOperand(N, 0); } - case ISD::SRA: { - unsigned Imm; - if (isIntImmediate(N->getOperand(1), Imm)) - CurDAG->SelectNodeTo(N, PPC::SRAWI, MVT::i32, Select(N->getOperand(0)), - getI32Imm(Imm)); - else - CurDAG->SelectNodeTo(N, PPC::SRAW, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); - } - case ISD::FMUL: { - unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FMULS : PPC::FMUL; - CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); - } - case ISD::FDIV: { - unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FDIVS : PPC::FDIV; - CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); - } - case ISD::FABS: - if (N->getValueType(0) == MVT::f32) - CurDAG->SelectNodeTo(N, PPC::FABSS, MVT::f32, Select(N->getOperand(0))); - else - CurDAG->SelectNodeTo(N, PPC::FABSD, MVT::f64, Select(N->getOperand(0))); - return SDOperand(N, 0); case ISD::FNEG: { SDOperand Val = Select(N->getOperand(0)); MVT::ValueType Ty = N->getValueType(0); @@ -1336,12 +1308,6 @@ CurDAG->SelectNodeTo(N, PPC::FNEGD, MVT::f64, Val); return SDOperand(N, 0); } - case ISD::FSQRT: { - MVT::ValueType Ty = N->getValueType(0); - CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FSQRT : PPC::FSQRTS, Ty, - Select(N->getOperand(0))); - return SDOperand(N, 0); - } case ISD::LOAD: case ISD::EXTLOAD: case ISD::ZEXTLOAD: From lattner at cs.uiuc.edu Sat Oct 15 16:59:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 15 Oct 2005 16:59:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp PPCTargetMachine.h Message-ID: <200510152159.QAA10522@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCCodeEmitter.cpp updated: 1.38 -> 1.39 PPCTargetMachine.h updated: 1.12 -> 1.13 --- Log message: prune #includes --- Diffs of the changes: (+2 -3) PPCCodeEmitter.cpp | 1 + PPCTargetMachine.h | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.38 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.39 --- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.38 Fri Oct 14 18:59:06 2005 +++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Sat Oct 15 16:58:54 2005 @@ -16,6 +16,7 @@ #include "PPCRelocations.h" #include "PPC.h" #include "llvm/Module.h" +#include "llvm/PassManager.h" #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" Index: llvm/lib/Target/PowerPC/PPCTargetMachine.h diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.12 llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.13 --- llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.12 Fri Oct 14 18:59:06 2005 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.h Sat Oct 15 16:58:54 2005 @@ -19,11 +19,9 @@ #include "PPCJITInfo.h" #include "PPCInstrInfo.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetFrameInfo.h" -#include "llvm/PassManager.h" namespace llvm { - +class PassManager; class IntrinsicLowering; class GlobalValue; class IntrinsicLowering; From lattner at cs.uiuc.edu Sat Oct 15 17:06:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 15 Oct 2005 17:06:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200510152206.RAA10621@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.105 -> 1.106 --- Log message: Remove some dead code: the ORI/ORIS cases are autogen'd. This makes SelectIntImmediateExpr dead. --- Diffs of the changes: (+1 -42) PPCISelDAGToDAG.cpp | 43 +------------------------------------------ 1 files changed, 1 insertion(+), 42 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.105 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.106 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.105 Sat Oct 15 16:44:56 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Sat Oct 15 17:06:18 2005 @@ -63,10 +63,6 @@ // target-specific node if it hasn't already been changed. SDOperand Select(SDOperand Op); - SDNode *SelectIntImmediateExpr(SDOperand LHS, SDOperand RHS, - unsigned OCHi, unsigned OCLo, - bool IsArithmetic = false, - bool Negate = false); SDNode *SelectBitfieldInsert(SDNode *N); /// SelectCC - Select a comparison of the specified values with the @@ -393,38 +389,6 @@ return 0; } -// SelectIntImmediateExpr - Choose code for integer operations with an immediate -// operand. -SDNode *PPC32DAGToDAGISel::SelectIntImmediateExpr(SDOperand LHS, SDOperand RHS, - unsigned OCHi, unsigned OCLo, - bool IsArithmetic, - bool Negate) { - // Check to make sure this is a constant. - ConstantSDNode *CN = dyn_cast(RHS); - // Exit if not a constant. - if (!CN) return 0; - // Extract immediate. - unsigned C = (unsigned)CN->getValue(); - // Negate if required (ISD::SUB). - if (Negate) C = -C; - // Get the hi and lo portions of constant. - unsigned Hi = IsArithmetic ? HA16(C) : Hi16(C); - unsigned Lo = Lo16(C); - - // If two instructions are needed and usage indicates it would be better to - // load immediate into a register, bail out. - if (Hi && Lo && CN->use_size() > 2) return false; - - // Select the first operand. - SDOperand Opr0 = Select(LHS); - - if (Lo) // Add in the lo-part. - Opr0 = CurDAG->getTargetNode(OCLo, MVT::i32, Opr0, getI32Imm(Lo)); - if (Hi) // Add in the hi-part. - Opr0 = CurDAG->getTargetNode(OCHi, MVT::i32, Opr0, getI32Imm(Hi)); - return Opr0.Val; -} - /// SelectAddr - Given the specified address, return the two operands for a /// load/store instruction, and return true if it should be an indexed [r+r] /// operation. @@ -1237,11 +1201,6 @@ case ISD::OR: if (SDNode *I = SelectBitfieldInsert(N)) return CodeGenMap[Op] = SDOperand(I, 0); - - if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), - N->getOperand(1), - PPC::ORIS, PPC::ORI)) - return CodeGenMap[Op] = SDOperand(I, 0); // Other cases are autogenerated. break; @@ -1279,7 +1238,7 @@ case ISD::FNEG: { SDOperand Val = Select(N->getOperand(0)); MVT::ValueType Ty = N->getValueType(0); - if (Val.Val->hasOneUse()) { + if (N->getOperand(0).Val->hasOneUse()) { unsigned Opc; switch (Val.isTargetOpcode() ? Val.getTargetOpcode() : 0) { default: Opc = 0; break; From natebegeman at mac.com Sat Oct 15 17:08:14 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sat, 15 Oct 2005 17:08:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200510152208.RAA10638@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.182 -> 1.183 --- Log message: Remove some dead code now that the dag combiner exists. --- Diffs of the changes: (+0 -15) X86ISelPattern.cpp | 15 --------------- 1 files changed, 15 deletions(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.182 llvm/lib/Target/X86/X86ISelPattern.cpp:1.183 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.182 Fri Oct 14 17:06:00 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Sat Oct 15 17:08:02 2005 @@ -2428,21 +2428,6 @@ return Result; } case ISD::TRUNCATE: - // Fold TRUNCATE (LOAD P) into a smaller load from P. - // FIXME: This should be performed by the DAGCombiner. - if (isFoldableLoad(N.getOperand(0), SDOperand())) { - switch (N.getValueType()) { - default: assert(0 && "Unknown truncate!"); - case MVT::i1: - case MVT::i8: Opc = X86::MOV8rm; break; - case MVT::i16: Opc = X86::MOV16rm; break; - } - X86AddressMode AM; - EmitFoldedLoad(N.getOperand(0), AM); - addFullAddress(BuildMI(BB, Opc, 4, Result), AM); - return Result; - } - // Handle cast of LARGER int to SMALLER int using a move to EAX followed by // a move out of AX or AL. switch (N.getOperand(0).getValueType()) { From lattner at cs.uiuc.edu Sat Oct 15 17:18:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 15 Oct 2005 17:18:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510152218.RAA10775@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.41 -> 1.42 --- Log message: Add a case we were missing that was causing us to fail CodeGen/PowerPC/rlwinm.ll:test3 --- Diffs of the changes: (+14 -0) DAGCombiner.cpp | 14 ++++++++++++++ 1 files changed, 14 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.41 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.42 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.41 Thu Oct 13 20:29:07 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sat Oct 15 17:18:08 2005 @@ -803,6 +803,20 @@ WorkList.push_back(ANDNode.Val); return DAG.getNode(N0.getOpcode(), VT, ANDNode, N0.getOperand(1)); } + // fold (and (sra)) -> (and (srl)) when possible. + if (N0.getOpcode() == ISD::SRA && N0.Val->hasOneUse()) + if (ConstantSDNode *N01C = dyn_cast(N0.getOperand(1))) { + // If the RHS of the AND has zeros where the sign bits of the SRA will + // land, turn the SRA into an SRL. + if (MaskedValueIsZero(N1, (~0ULL << N01C->getValue()) & + (~0ULL>>(64-OpSizeInBits)), TLI)) { + WorkList.push_back(N); + CombineTo(N0.Val, DAG.getNode(ISD::SRL, VT, N0.getOperand(0), + N0.getOperand(1))); + return SDOperand(); + } + } + // fold (zext_inreg (extload x)) -> (zextload x) if (N0.getOpcode() == ISD::EXTLOAD) { MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); From lattner at cs.uiuc.edu Sat Oct 15 17:35:52 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 15 Oct 2005 17:35:52 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510152235.RAA10835@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.42 -> 1.43 --- Log message: Fix this logic. --- Diffs of the changes: (+1 -1) DAGCombiner.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.42 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.43 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.42 Sat Oct 15 17:18:08 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sat Oct 15 17:35:40 2005 @@ -808,7 +808,7 @@ if (ConstantSDNode *N01C = dyn_cast(N0.getOperand(1))) { // If the RHS of the AND has zeros where the sign bits of the SRA will // land, turn the SRA into an SRL. - if (MaskedValueIsZero(N1, (~0ULL << N01C->getValue()) & + if (MaskedValueIsZero(N1, (~0ULL << (OpSizeInBits-N01C->getValue())) & (~0ULL>>(64-OpSizeInBits)), TLI)) { WorkList.push_back(N); CombineTo(N0.Val, DAG.getNode(ISD::SRL, VT, N0.getOperand(0), From lattner at cs.uiuc.edu Sat Oct 15 19:36:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 15 Oct 2005 19:36:49 -0500 Subject: [llvm-commits] CVS: llvm/docs/CodeGenerator.html Message-ID: <200510160036.TAA11257@zion.cs.uiuc.edu> Changes in directory llvm/docs: CodeGenerator.html updated: 1.18 -> 1.19 --- Log message: update this a little bit to talk about the dag combiner and remove inaccuracies. This still doesn't talk about autogen much --- Diffs of the changes: (+45 -31) CodeGenerator.html | 76 +++++++++++++++++++++++++++++++---------------------- 1 files changed, 45 insertions(+), 31 deletions(-) Index: llvm/docs/CodeGenerator.html diff -u llvm/docs/CodeGenerator.html:1.18 llvm/docs/CodeGenerator.html:1.19 --- llvm/docs/CodeGenerator.html:1.18 Fri Sep 30 12:46:55 2005 +++ llvm/docs/CodeGenerator.html Sat Oct 15 19:36:38 2005 @@ -15,7 +15,8 @@
  • Introduction
  • @@ -46,8 +47,10 @@ Construction
  • SelectionDAG Legalize Phase
  • SelectionDAG Optimization - Phase
  • + Phase: the DAG Combiner
  • SelectionDAG Select Phase
  • +
  • SelectionDAG Scheduling and Emission + Phase
  • Future directions for the SelectionDAG
  • @@ -631,23 +634,15 @@ Instruction Selection is the process of translating LLVM code presented to the code generator into target-specific machine instructions. There are several well-known ways to do this in the literature. In LLVM there are two main forms: -the old-style 'simple' instruction selector (which effectively peephole selects -each LLVM instruction into a series of machine instructions), and the new -SelectionDAG based instruction selector. -

    - -

    The 'simple' instruction selectors are tedious to write, require a lot of -boiler plate code, and are difficult to get correct. Additionally, any -optimizations written for a simple instruction selector cannot be used by other -targets. For this reason, LLVM is moving to a new SelectionDAG based -instruction selector, which is described in this section. If you are starting a -new port, we recommend that you write the instruction selector using the -SelectionDAG infrastructure.

    - -

    In time, most of the target-specific code for instruction selection will be -auto-generated from the target description (*.td) files. For now, -however, the Select Phase must still be -written by hand.

    +the SelectionDAG based instruction selector framework and an old-style 'simple' +instruction selector (which effectively peephole selects each LLVM instruction +into a series of machine instructions). We recommend that all targets use the +SelectionDAG infrastructure. +

    + +

    Portions of the DAG instruction selector are generated from the target +description files (*.td) files. Eventually, we aim for the entire +instruction selector to be generated from these .td files.

    @@ -744,8 +739,12 @@ eliminate inefficiencies introduced by legalization.
  • Select instructions from DAG - Finally, the target instruction selector matches the DAG operations to target - instructions, emitting them and building the MachineFunction being - compiled.
  • + instructions. This process translates the target-independent input DAG into + another DAG of target instructions. +
  • SelectionDAG Scheduling and Emission + - The last phase assigns a linear order to the instructions in the + target-instruction DAG and emits them into the MachineFunction being + compiled. This step uses traditional prepass scheduling techniques.
  • After all of these steps are complete, the SelectionDAG is destroyed and the @@ -822,7 +821,8 @@

    @@ -838,8 +838,9 @@

    -One important class of optimizations that this pass will do in the future is -optimizing inserted sign and zero extension instructions. Here are some good +One important class of optimizations performed is optimizing inserted sign and +zero extension instructions. We currently use ad-hoc techniques, but could move +to more rigorous techniques in the future. Here are some good papers on the subject:

    @@ -877,18 +878,31 @@

    + +
    + +

    The scheduling phase takes the DAG of target instructions from the selection +phase and assigns an order. The scheduler can pick an order depending on +various constraints of the machines (i.e. order for minimal register pressure or +try to cover instruction latencies). Once an order is established, the DAG is +converted to a list of MachineInstrs and the +Selection DAG is destroyed. +

    + +
    + + +
      -
    1. Optional whole-function selection.
    2. -
    3. Select is a graph translation phase.
    4. -
    5. Place the machine instructions resulting from Select according to register -pressure or a schedule.
    6. -
    7. DAG Scheduling.
    8. -
    9. Auto-generate the Select phase from the target description (*.td) files. +
    10. Optional function-at-a-time selection.
    11. +
    12. Auto-generate entire selector from .td file.
    @@ -1032,7 +1046,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/09/30 17:46:55 $ + Last modified: $Date: 2005/10/16 00:36:38 $ From lattner at cs.uiuc.edu Sat Oct 15 20:42:10 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 15 Oct 2005 20:42:10 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200510160142.UAA11504@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.57 -> 1.58 DAGISelEmitter.h updated: 1.32 -> 1.33 --- Log message: Make the generated code significantly more memory efficient, by using SelectNodeTo instead of getTargetNode when possible. --- Diffs of the changes: (+37 -14) DAGISelEmitter.cpp | 49 ++++++++++++++++++++++++++++++++++++------------- DAGISelEmitter.h | 2 +- 2 files changed, 37 insertions(+), 14 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.57 llvm/utils/TableGen/DAGISelEmitter.cpp:1.58 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.57 Sat Oct 15 16:34:21 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Sat Oct 15 20:41:58 2005 @@ -1554,9 +1554,10 @@ unsigned DAGISelEmitter:: CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, std::map &VariableMap, - std::ostream &OS) { + std::ostream &OS, 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!"); @@ -1603,12 +1604,33 @@ CodeGenInstruction &II = Target.getInstruction(Op->getName()); unsigned ResNo = Ctr++; - OS << " SDOperand Tmp" << ResNo << " = 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]; - OS << ");\n"; + if (!isRoot) { + OS << " SDOperand Tmp" << ResNo << " = 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]; + OS << ");\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. + OS << " if (N.Val->hasOneUse()) {\n"; + OS << " 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]; + OS << ");\n"; + OS << " return N;\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]; + OS << ");\n"; + OS << " }\n"; + } return ResNo; } else if (Op->isSubClassOf("SDNodeXForm")) { assert(N->getNumChildren() == 1 && "node xform should have one child!"); @@ -1617,6 +1639,10 @@ 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 ResNo; } else { N->dump(); @@ -1712,13 +1738,10 @@ // an unresolved type to add a check for, this returns true and we iterate, // otherwise we are done. } while (InsertOneTypeCheck(Pat, Pattern.first, "N", PatternNo, OS)); - - unsigned TmpNo = 0; - unsigned Res = CodeGenPatternResult(Pattern.second, TmpNo, VariableMap, OS); - // Add the result to the map if it has multiple uses. - OS << " if (!N.Val->hasOneUse()) CodeGenMap[N] = Tmp" << Res << ";\n"; - OS << " return Tmp" << Res << ";\n"; + unsigned TmpNo = 0; + CodeGenPatternResult(Pattern.second, TmpNo, + VariableMap, OS, 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.32 llvm/utils/TableGen/DAGISelEmitter.h:1.33 --- llvm/utils/TableGen/DAGISelEmitter.h:1.32 Fri Oct 14 01:12:03 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Sat Oct 15 20:41:58 2005 @@ -411,7 +411,7 @@ unsigned PatternNo, std::ostream &OS); unsigned CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, std::map &VariableMap, - std::ostream &OS); + std::ostream &OS, bool isRoot = false); void EmitCodeForPattern(PatternToMatch &Pattern, std::ostream &OS); void EmitInstructionSelector(std::ostream &OS); }; From natebegeman at mac.com Sun Oct 16 00:40:02 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sun, 16 Oct 2005 00:40:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp PPCBranchSelector.cpp PPCCodeEmitter.cpp PPCFrameInfo.h PPCISelDAGToDAG.cpp PPCISelLowering.cpp PPCISelLowering.h PPCISelPattern.cpp PPCInstrBuilder.h PPCInstrInfo.cpp PPCInstrInfo.h PPCJITInfo.cpp PPCJITInfo.h PPCRegisterInfo.cpp PPCRegisterInfo.h PPCRelocations.h PPCSubtarget.h PPCTargetMachine.cpp PPCTargetMachine.h README.txt Message-ID: <200510160540.AAA12224@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.98 -> 1.99 PPCBranchSelector.cpp updated: 1.19 -> 1.20 PPCCodeEmitter.cpp updated: 1.39 -> 1.40 PPCFrameInfo.h updated: 1.8 -> 1.9 PPCISelDAGToDAG.cpp updated: 1.106 -> 1.107 PPCISelLowering.cpp updated: 1.30 -> 1.31 PPCISelLowering.h updated: 1.7 -> 1.8 PPCISelPattern.cpp updated: 1.188 -> 1.189 PPCInstrBuilder.h updated: 1.3 -> 1.4 PPCInstrInfo.cpp updated: 1.10 -> 1.11 PPCInstrInfo.h updated: 1.6 -> 1.7 PPCJITInfo.cpp updated: 1.16 -> 1.17 PPCJITInfo.h updated: 1.7 -> 1.8 PPCRegisterInfo.cpp updated: 1.33 -> 1.34 PPCRegisterInfo.h updated: 1.8 -> 1.9 PPCRelocations.h updated: 1.5 -> 1.6 PPCSubtarget.h updated: 1.6 -> 1.7 PPCTargetMachine.cpp updated: 1.73 -> 1.74 PPCTargetMachine.h updated: 1.13 -> 1.14 README.txt updated: 1.31 -> 1.32 --- Log message: More PPC32 -> PPC changes, as well as merging some classes that were redundant after the change. --- Diffs of the changes: (+152 -170) PPCAsmPrinter.cpp | 6 +-- PPCBranchSelector.cpp | 4 +- PPCCodeEmitter.cpp | 6 +-- PPCFrameInfo.h | 8 ++--- PPCISelDAGToDAG.cpp | 8 ++--- PPCISelLowering.cpp | 36 +++++++++++----------- PPCISelLowering.h | 6 +-- PPCISelPattern.cpp | 4 +- PPCInstrBuilder.h | 2 - PPCInstrInfo.cpp | 12 +++---- PPCInstrInfo.h | 8 ++--- PPCJITInfo.cpp | 12 +++---- PPCJITInfo.h | 12 +------ PPCRegisterInfo.cpp | 44 +++++++++++++-------------- PPCRegisterInfo.h | 6 +-- PPCRelocations.h | 2 - PPCSubtarget.h | 2 - PPCTargetMachine.cpp | 80 +++++++++++++++++++++----------------------------- PPCTargetMachine.h | 51 +++++++++++-------------------- README.txt | 13 ++++++++ 20 files changed, 152 insertions(+), 170 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.98 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.99 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.98 Fri Oct 14 18:59:06 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --===// +//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --------=// // // The LLVM Compiler Infrastructure // @@ -57,8 +57,8 @@ return "PowerPC Assembly Printer"; } - PowerPCTargetMachine &getTM() { - return static_cast(TM); + PPCTargetMachine &getTM() { + return static_cast(TM); } unsigned enumRegToMachineReg(unsigned enumReg) { Index: llvm/lib/Target/PowerPC/PPCBranchSelector.cpp diff -u llvm/lib/Target/PowerPC/PPCBranchSelector.cpp:1.19 llvm/lib/Target/PowerPC/PPCBranchSelector.cpp:1.20 --- llvm/lib/Target/PowerPC/PPCBranchSelector.cpp:1.19 Fri Oct 14 18:59:06 2005 +++ llvm/lib/Target/PowerPC/PPCBranchSelector.cpp Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===-- PowerPCBranchSelector.cpp - Emit long conditional branches-*- C++ -*-=// +//===-- PPCBranchSelector.cpp - Emit long conditional branches-----*- C++ -*-=// // // The LLVM Compiler Infrastructure // @@ -107,7 +107,7 @@ int Displacement = OffsetMap[trueMBB] - ByteCount; unsigned Opcode = MBBI->getOperand(1).getImmedValue(); unsigned CRReg = MBBI->getOperand(0).getReg(); - unsigned Inverted = PPC32InstrInfo::invertPPCBranchOpcode(Opcode); + unsigned Inverted = PPCInstrInfo::invertPPCBranchOpcode(Opcode); if (Displacement >= -32768 && Displacement <= 32767) { BuildMI(*MBB, MBBJ, Opcode, 2).addReg(CRReg).addMBB(trueMBB); Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.39 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.40 --- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.39 Sat Oct 15 16:58:54 2005 +++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===-- PPCCodeEmitter.cpp - JIT Code Emitter for PowerPC32 -----*- C++ -*-=// +//===-- PPCCodeEmitter.cpp - JIT Code Emitter for PowerPC32 -------*- C++ -*-=// // // The LLVM Compiler Infrastructure // @@ -74,8 +74,8 @@ /// of functions. This method should returns true if machine code emission is /// not supported. /// -bool PPC32TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM, - MachineCodeEmitter &MCE) { +bool PPCTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM, + MachineCodeEmitter &MCE) { // Machine code emitter pass for PowerPC PM.add(new PPCCodeEmitter(*this, MCE)); // Delete machine code for this function after emitting it Index: llvm/lib/Target/PowerPC/PPCFrameInfo.h diff -u llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.8 llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.9 --- llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.8 Fri Oct 14 18:51:18 2005 +++ llvm/lib/Target/PowerPC/PPCFrameInfo.h Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===-- PowerPCFrameInfo.h - Define TargetFrameInfo for PowerPC -*- C++ -*-===// +//===-- PPCFrameInfo.h - Define TargetFrameInfo for PowerPC -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // -//---------------------------------------------------------------------------- +//===----------------------------------------------------------------------===// #ifndef POWERPC_FRAMEINFO_H #define POWERPC_FRAMEINFO_H @@ -19,12 +19,12 @@ namespace llvm { -class PowerPCFrameInfo: public TargetFrameInfo { +class PPCFrameInfo: public TargetFrameInfo { const TargetMachine &TM; std::pair LR[1]; public: - PowerPCFrameInfo(const TargetMachine &tm, bool LP64) + PPCFrameInfo(const TargetMachine &tm, bool LP64) : TargetFrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0), TM(tm) { LR[0].first = PPC::LR; LR[0].second = LP64 ? 16 : 8; Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.106 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.107 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.106 Sat Oct 15 17:06:18 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===-- PPC32ISelDAGToDAG.cpp - PPC32 pattern matching inst selector ------===// +//===-- PPCISelDAGToDAG.cpp - PPC --pattern matching inst selector --------===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file defines a pattern matching instruction selector for 32 bit PowerPC, +// This file defines a pattern matching instruction selector for PowerPC, // converting from a legalized dag to a PPC dag. // //===----------------------------------------------------------------------===// @@ -37,11 +37,11 @@ /// instructions for SelectionDAG operations. /// class PPC32DAGToDAGISel : public SelectionDAGISel { - PPC32TargetLowering PPC32Lowering; + PPCTargetLowering PPCLowering; unsigned GlobalBaseReg; public: PPC32DAGToDAGISel(TargetMachine &TM) - : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM) {} + : SelectionDAGISel(PPCLowering), PPCLowering(TM) {} virtual bool runOnFunction(Function &Fn) { // Make sure we re-emit a set of the global base reg if necessary Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.30 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.31 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.30 Fri Oct 14 18:59:06 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===-- PPC32ISelLowering.cpp - PPC32 DAG Lowering Implementation ---------===// +//===-- PPCISelLowering.cpp - PPC32 DAG Lowering Implementation -----------===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements the PPC32ISelLowering class. +// This file implements the PPCISelLowering class. // //===----------------------------------------------------------------------===// @@ -22,7 +22,7 @@ #include "llvm/Function.h" using namespace llvm; -PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM) +PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) : TargetLowering(TM) { // Fold away setcc operations if possible. @@ -125,7 +125,7 @@ /// LowerOperation - Provide custom lowering hooks for some operations. /// -SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { +SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { default: assert(0 && "Wasn't expecting to be able to lower this!"); case ISD::FP_TO_SINT: { @@ -311,7 +311,7 @@ } std::vector -PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { +PPCTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { // // add beautiful description of PPC stack frame format, or at least some docs // @@ -490,11 +490,11 @@ } std::pair -PPC32TargetLowering::LowerCallTo(SDOperand Chain, - const Type *RetTy, bool isVarArg, - unsigned CallingConv, bool isTailCall, - SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG) { +PPCTargetLowering::LowerCallTo(SDOperand Chain, + const Type *RetTy, bool isVarArg, + unsigned CallingConv, bool isTailCall, + SDOperand Callee, ArgListTy &Args, + SelectionDAG &DAG) { // args_to_use will accumulate outgoing args for the ISD::CALL case in // SelectExpr to use to put the arguments in the appropriate registers. std::vector args_to_use; @@ -687,8 +687,8 @@ return std::make_pair(RetVal, Chain); } -SDOperand PPC32TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG) { +SDOperand PPCTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG) { // vastart just stores the address of the VarArgsFrameIndex slot into the // memory location argument. SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); @@ -697,9 +697,9 @@ } std::pair -PPC32TargetLowering::LowerVAArg(SDOperand Chain, - SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG) { +PPCTargetLowering::LowerVAArg(SDOperand Chain, + SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG) { MVT::ValueType ArgVT = getValueType(ArgTy); SDOperand VAList = @@ -721,7 +721,7 @@ } -std::pair PPC32TargetLowering:: +std::pair PPCTargetLowering:: LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, SelectionDAG &DAG) { assert(0 && "LowerFrameReturnAddress unimplemented"); @@ -729,8 +729,8 @@ } MachineBasicBlock * -PPC32TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, - MachineBasicBlock *BB) { +PPCTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, + MachineBasicBlock *BB) { assert((MI->getOpcode() == PPC::SELECT_CC_Int || MI->getOpcode() == PPC::SELECT_CC_F4 || MI->getOpcode() == PPC::SELECT_CC_F8) && Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.7 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.8 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.7 Fri Oct 14 18:51:18 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===-- PPC32ISelLowering.h - PPC32 DAG Lowering Interface ------*- C++ -*-===// +//===-- PPCISelLowering.h - PPC32 DAG Lowering Interface --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -41,11 +41,11 @@ }; } - class PPC32TargetLowering : public TargetLowering { + class PPCTargetLowering : public TargetLowering { int VarArgsFrameIndex; // FrameIndex for start of varargs area. int ReturnAddrIndex; // FrameIndex for return slot. public: - PPC32TargetLowering(TargetMachine &TM); + PPCTargetLowering(TargetMachine &TM); /// LowerOperation - Provide custom lowering hooks for some operations. /// Index: llvm/lib/Target/PowerPC/PPCISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.188 llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.189 --- llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.188 Sat Oct 15 14:04:48 2005 +++ llvm/lib/Target/PowerPC/PPCISelPattern.cpp Sun Oct 16 00:39:50 2005 @@ -44,7 +44,7 @@ //===--------------------------------------------------------------------===// class ISel : public SelectionDAGISel { - PPC32TargetLowering PPC32Lowering; + PPCTargetLowering PPCLowering; SelectionDAG *ISelDAG; // Hack to support us having a dag->dag transform // for sdiv and udiv until it is put into the future // dag combiner. @@ -58,7 +58,7 @@ bool GlobalBaseInitialized; bool RecordSuccess; public: - ISel(TargetMachine &TM) : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM), + ISel(TargetMachine &TM) : SelectionDAGISel(PPCLowering), PPCLowering(TM), ISelDAG(0) {} /// runOnFunction - Override this function in order to reset our per-function Index: llvm/lib/Target/PowerPC/PPCInstrBuilder.h diff -u llvm/lib/Target/PowerPC/PPCInstrBuilder.h:1.3 llvm/lib/Target/PowerPC/PPCInstrBuilder.h:1.4 --- llvm/lib/Target/PowerPC/PPCInstrBuilder.h:1.3 Thu Apr 21 18:20:02 2005 +++ llvm/lib/Target/PowerPC/PPCInstrBuilder.h Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===-- PowerPCInstrBuilder.h - Aides for building PPC insts ----*- C++ -*-===// +//===-- PPCInstrBuilder.h - Aides for building PPC insts --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // Index: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.10 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.11 --- llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.10 Fri Oct 14 18:59:06 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.cpp Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===- PPC32InstrInfo.cpp - PowerPC32 Instruction Information ---*- C++ -*-===// +//===- PPCInstrInfo.cpp - PowerPC32 Instruction Information -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,12 +18,12 @@ #include using namespace llvm; -PPC32InstrInfo::PPC32InstrInfo() +PPCInstrInfo::PPCInstrInfo() : TargetInstrInfo(PPCInsts, sizeof(PPCInsts)/sizeof(PPCInsts[0])) {} -bool PPC32InstrInfo::isMoveInstr(const MachineInstr& MI, - unsigned& sourceReg, - unsigned& destReg) const { +bool PPCInstrInfo::isMoveInstr(const MachineInstr& MI, + unsigned& sourceReg, + unsigned& destReg) const { MachineOpCode oc = MI.getOpcode(); if (oc == PPC::OR) { // or r1, r2, r2 assert(MI.getNumOperands() == 3 && @@ -80,7 +80,7 @@ // commuteInstruction - We can commute rlwimi instructions, but only if the // rotate amt is zero. We also have to munge the immediates a bit. -MachineInstr *PPC32InstrInfo::commuteInstruction(MachineInstr *MI) const { +MachineInstr *PPCInstrInfo::commuteInstruction(MachineInstr *MI) const { // Normal instructions can be commuted the obvious way. if (MI->getOpcode() != PPC::RLWIMI) return TargetInstrInfo::commuteInstruction(MI); Index: llvm/lib/Target/PowerPC/PPCInstrInfo.h diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.6 llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.7 --- llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.6 Fri Oct 14 18:59:06 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.h Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===- PPC32InstrInfo.h - PowerPC32 Instruction Information -----*- C++ -*-===// +//===- PPCInstrInfo.h - PowerPC32 Instruction Information -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -20,10 +20,10 @@ namespace llvm { -class PPC32InstrInfo : public TargetInstrInfo { - const PPC32RegisterInfo RI; +class PPCInstrInfo : public TargetInstrInfo { + const PPCRegisterInfo RI; public: - PPC32InstrInfo(); + PPCInstrInfo(); /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As /// such, whenever a client has an instance of instruction info, it should Index: llvm/lib/Target/PowerPC/PPCJITInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCJITInfo.cpp:1.16 llvm/lib/Target/PowerPC/PPCJITInfo.cpp:1.17 --- llvm/lib/Target/PowerPC/PPCJITInfo.cpp:1.16 Fri Oct 14 18:59:06 2005 +++ llvm/lib/Target/PowerPC/PPCJITInfo.cpp Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===-- PPC32JITInfo.cpp - Implement the JIT interfaces for the PowerPC ---===// +//===-- PPCJITInfo.cpp - Implement the JIT interfaces for the PowerPC -----===// // // The LLVM Compiler Infrastructure // @@ -154,12 +154,12 @@ TargetJITInfo::LazyResolverFn -PPC32JITInfo::getLazyResolverFunction(JITCompilerFn Fn) { +PPCJITInfo::getLazyResolverFunction(JITCompilerFn Fn) { JITCompilerFunction = Fn; return PPC32CompilationCallback; } -void *PPC32JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) { +void *PPCJITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) { // If this is just a call to an external function, emit a branch instead of a // call. The code is the same except for one bit of the last instruction. if (Fn != PPC32CompilationCallback) { @@ -187,8 +187,8 @@ } -void PPC32JITInfo::relocate(void *Function, MachineRelocation *MR, - unsigned NumRelocs, unsigned char* GOTBase) { +void PPCJITInfo::relocate(void *Function, MachineRelocation *MR, + unsigned NumRelocs, unsigned char* GOTBase) { for (unsigned i = 0; i != NumRelocs; ++i, ++MR) { unsigned *RelocPos = (unsigned*)Function + MR->getMachineCodeOffset()/4; intptr_t ResultPtr = (intptr_t)MR->getResultPointer(); @@ -238,6 +238,6 @@ } } -void PPC32JITInfo::replaceMachineCodeForFunction(void *Old, void *New) { +void PPCJITInfo::replaceMachineCodeForFunction(void *Old, void *New) { EmitBranchToAt(Old, New, false); } Index: llvm/lib/Target/PowerPC/PPCJITInfo.h diff -u llvm/lib/Target/PowerPC/PPCJITInfo.h:1.7 llvm/lib/Target/PowerPC/PPCJITInfo.h:1.8 --- llvm/lib/Target/PowerPC/PPCJITInfo.h:1.7 Fri Oct 14 18:53:41 2005 +++ llvm/lib/Target/PowerPC/PPCJITInfo.h Sun Oct 16 00:39:50 2005 @@ -19,24 +19,18 @@ namespace llvm { class TargetMachine; - // FIXME: Merge into one PPCJITInfo class. - class PowerPCJITInfo : public TargetJITInfo { + class PPCJITInfo : public TargetJITInfo { protected: TargetMachine &TM; public: - PowerPCJITInfo(TargetMachine &tm) : TM(tm) {useGOT = 0;} + PPCJITInfo(TargetMachine &tm) : TM(tm) {useGOT = 0;} /// addPassesToJITCompile - Add passes to the specified pass manager to /// implement a fast dynamic compiler for this target. Return true if this /// is not supported for this target. /// virtual void addPassesToJITCompile(FunctionPassManager &PM); - }; - - class PPC32JITInfo : public PowerPCJITInfo { - public: - PPC32JITInfo(TargetMachine &tm) : PowerPCJITInfo(tm) {} - + virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE); virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn); virtual void relocate(void *Function, MachineRelocation *MR, Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.33 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.34 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.33 Fri Oct 14 18:59:06 2005 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===- PPC32RegisterInfo.cpp - PowerPC32 Register Information ---*- C++ -*-===// +//===- PPCRegisterInfo.cpp - PowerPC Register Information -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file contains the PowerPC32 implementation of the MRegisterInfo class. +// This file contains the PowerPC implementation of the MRegisterInfo class. // //===----------------------------------------------------------------------===// @@ -31,7 +31,7 @@ #include using namespace llvm; -PPC32RegisterInfo::PPC32RegisterInfo() +PPCRegisterInfo::PPCRegisterInfo() : PPCGenRegisterInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP) { ImmToIdxMap[PPC::LD] = PPC::LDX; ImmToIdxMap[PPC::STD] = PPC::STDX; ImmToIdxMap[PPC::LBZ] = PPC::LBZX; ImmToIdxMap[PPC::STB] = PPC::STBX; @@ -44,10 +44,10 @@ } void -PPC32RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx, - const TargetRegisterClass *RC) const { +PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned SrcReg, int FrameIdx, + const TargetRegisterClass *RC) const { if (SrcReg == PPC::LR) { BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11); addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx); @@ -67,7 +67,7 @@ } void -PPC32RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, +PPCRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC) const { @@ -89,10 +89,10 @@ } } -void PPC32RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const { +void PPCRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, unsigned SrcReg, + const TargetRegisterClass *RC) const { MachineInstr *I; if (RC == PPC32::GPRCRegisterClass) { @@ -109,8 +109,8 @@ } } -unsigned PPC32RegisterInfo::isLoadFromStackSlot(MachineInstr *MI, - int &FrameIndex) const { +unsigned PPCRegisterInfo::isLoadFromStackSlot(MachineInstr *MI, + int &FrameIndex) const { switch (MI->getOpcode()) { default: break; case PPC::LWZ: @@ -128,9 +128,9 @@ /// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into /// copy instructions, turning them into load/store instructions. -MachineInstr *PPC32RegisterInfo::foldMemoryOperand(MachineInstr *MI, - unsigned OpNum, - int FrameIndex) const { +MachineInstr *PPCRegisterInfo::foldMemoryOperand(MachineInstr *MI, + unsigned OpNum, + int FrameIndex) const { // Make sure this is a reg-reg copy. Note that we can't handle MCRF, because // it takes more than one instruction to store it. unsigned Opc = MI->getOpcode(); @@ -180,7 +180,7 @@ return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects(); } -void PPC32RegisterInfo:: +void PPCRegisterInfo:: eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { if (hasFP(MF)) { @@ -211,7 +211,7 @@ } void -PPC32RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { +PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { unsigned i = 0; MachineInstr &MI = *II; MachineBasicBlock &MBB = *MI.getParent(); @@ -261,7 +261,7 @@ } -void PPC32RegisterInfo::emitPrologue(MachineFunction &MF) const { +void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB MachineBasicBlock::iterator MBBI = MBB.begin(); MachineFrameInfo *MFI = MF.getFrameInfo(); @@ -320,8 +320,8 @@ } } -void PPC32RegisterInfo::emitEpilogue(MachineFunction &MF, - MachineBasicBlock &MBB) const { +void PPCRegisterInfo::emitEpilogue(MachineFunction &MF, + MachineBasicBlock &MBB) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); MachineBasicBlock::iterator MBBI = prior(MBB.end()); MachineInstr *MI; Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.h diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.h:1.8 llvm/lib/Target/PowerPC/PPCRegisterInfo.h:1.9 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.h:1.8 Fri Oct 14 18:51:18 2005 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.h Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===- PPC32RegisterInfo.h - PowerPC32 Register Information Impl -*- C++ -*-==// +//===- PPCRegisterInfo.h - PowerPC Register Information Impl -----*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -22,10 +22,10 @@ class Type; -class PPC32RegisterInfo : public PPCGenRegisterInfo { +class PPCRegisterInfo : public PPCGenRegisterInfo { std::map ImmToIdxMap; public: - PPC32RegisterInfo(); + PPCRegisterInfo(); /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, Index: llvm/lib/Target/PowerPC/PPCRelocations.h diff -u llvm/lib/Target/PowerPC/PPCRelocations.h:1.5 llvm/lib/Target/PowerPC/PPCRelocations.h:1.6 --- llvm/lib/Target/PowerPC/PPCRelocations.h:1.5 Wed Jul 27 00:53:43 2005 +++ llvm/lib/Target/PowerPC/PPCRelocations.h Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===- PPC32Relocations.h - PPC32 Code Relocations --------------*- C++ -*-===// +//===- PPCRelocations.h - PPC32 Code Relocations ----------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // Index: llvm/lib/Target/PowerPC/PPCSubtarget.h diff -u llvm/lib/Target/PowerPC/PPCSubtarget.h:1.6 llvm/lib/Target/PowerPC/PPCSubtarget.h:1.7 --- llvm/lib/Target/PowerPC/PPCSubtarget.h:1.6 Thu Sep 29 16:11:57 2005 +++ llvm/lib/Target/PowerPC/PPCSubtarget.h Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//=====-- PowerPCSubtarget.h - Define Subtarget for the PPC ---*- C++ -*--====// +//=====-- PPCSubtarget.h - Define Subtarget for the PPC -------*- C++ -*--====// // // The LLVM Compiler Infrastructure // Index: llvm/lib/Target/PowerPC/PPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.73 llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.74 --- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.73 Fri Oct 14 18:59:06 2005 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.cpp Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===-- PowerPCTargetMachine.cpp - Define TargetMachine for PowerPC -------===// +//===-- PPCTargetMachine.cpp - Define TargetMachine for PowerPC -----------===// // // The LLVM Compiler Infrastructure // @@ -29,30 +29,15 @@ using namespace llvm; namespace { - const char *PPC32ID = "PowerPC/32bit"; - static cl::opt DisablePPCDAGDAG("disable-ppc-dag-isel", cl::Hidden, cl::desc("Disable DAG-to-DAG isel for PPC")); // Register the targets - RegisterTarget - X("ppc32", " PowerPC 32-bit"); + RegisterTarget + X("ppc32", " PowerPC"); } -PowerPCTargetMachine::PowerPCTargetMachine(const std::string &name, - IntrinsicLowering *IL, - const Module &M, - const std::string &FS, - const TargetData &TD, - const PowerPCFrameInfo &TFI) -: TargetMachine(name, IL, TD), FrameInfo(TFI), Subtarget(M, FS) { - if (TargetDefault == PPCTarget) { - if (Subtarget.isAIX()) PPCTarget = TargetAIX; - if (Subtarget.isDarwin()) PPCTarget = TargetDarwin; - } -} - -unsigned PPC32TargetMachine::getJITMatchQuality() { +unsigned PPCTargetMachine::getJITMatchQuality() { #if defined(__POWERPC__) || defined (__ppc__) || defined(_POWER) return 10; #else @@ -60,12 +45,38 @@ #endif } +unsigned PPCTargetMachine::getModuleMatchQuality(const Module &M) { + // We strongly match "powerpc-*". + std::string TT = M.getTargetTriple(); + if (TT.size() >= 8 && std::string(TT.begin(), TT.begin()+8) == "powerpc-") + return 20; + + if (M.getEndianness() == Module::BigEndian && + M.getPointerSize() == Module::Pointer32) + return 10; // Weak match + else if (M.getEndianness() != Module::AnyEndianness || + M.getPointerSize() != Module::AnyPointerSize) + return 0; // Match for some other target + + return getJITMatchQuality()/2; +} + +PPCTargetMachine::PPCTargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS) +: TargetMachine("PowerPC", IL, false, 4, 4, 4, 4, 4, 4, 2, 1, 1), + Subtarget(M, FS), FrameInfo(*this, false), JITInfo(*this) { + if (TargetDefault == PPCTarget) { + if (Subtarget.isAIX()) PPCTarget = TargetAIX; + if (Subtarget.isDarwin()) PPCTarget = TargetDarwin; + } +} + /// addPassesToEmitFile - Add passes to the specified pass manager to implement /// a static compiler for this target. /// -bool PowerPCTargetMachine::addPassesToEmitFile(PassManager &PM, - std::ostream &Out, - CodeGenFileType FileType) { +bool PPCTargetMachine::addPassesToEmitFile(PassManager &PM, + std::ostream &Out, + CodeGenFileType FileType) { if (FileType != TargetMachine::AssemblyFile) return true; // Run loop strength reduction before anything else. @@ -121,7 +132,7 @@ return false; } -void PowerPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) { +void PPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) { // The JIT does not support or need PIC. PICEnabled = false; @@ -159,26 +170,3 @@ PM.add(createMachineFunctionPrinterPass(&std::cerr)); } -/// PowerPCTargetMachine ctor - Create an ILP32 architecture model -/// -PPC32TargetMachine::PPC32TargetMachine(const Module &M, IntrinsicLowering *IL, - const std::string &FS) - : PowerPCTargetMachine(PPC32ID, IL, M, FS, - TargetData(PPC32ID,false,4,4,4,4,4,4,2,1,1), - PowerPCFrameInfo(*this, false)), JITInfo(*this) {} - -unsigned PPC32TargetMachine::getModuleMatchQuality(const Module &M) { - // We strongly match "powerpc-*". - std::string TT = M.getTargetTriple(); - if (TT.size() >= 8 && std::string(TT.begin(), TT.begin()+8) == "powerpc-") - return 20; - - if (M.getEndianness() == Module::BigEndian && - M.getPointerSize() == Module::Pointer32) - return 10; // Weak match - else if (M.getEndianness() != Module::AnyEndianness || - M.getPointerSize() != Module::AnyPointerSize) - return 0; // Match for some other target - - return getJITMatchQuality()/2; -} Index: llvm/lib/Target/PowerPC/PPCTargetMachine.h diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.13 llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.14 --- llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.13 Sat Oct 15 16:58:54 2005 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.h Sun Oct 16 00:39:50 2005 @@ -1,4 +1,4 @@ -//===-- PPC32TargetMachine.h - Define TargetMachine for PowerPC -*- C++ -*-=// +//===-- PPCTargetMachine.h - Define TargetMachine for PowerPC -----*- C++ -*-=// // // The LLVM Compiler Infrastructure // @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef POWERPC32_TARGETMACHINE_H -#define POWERPC32_TARGETMACHINE_H +#ifndef PPC_TARGETMACHINE_H +#define PPC_TARGETMACHINE_H #include "PPCFrameInfo.h" #include "PPCSubtarget.h" @@ -26,47 +26,34 @@ class GlobalValue; class IntrinsicLowering; -// FIXME: Merge into only subclass. -class PowerPCTargetMachine : public TargetMachine { - PowerPCFrameInfo FrameInfo; - PPCSubtarget Subtarget; -protected: - PowerPCTargetMachine(const std::string &name, IntrinsicLowering *IL, - const Module &M, const std::string &FS, - const TargetData &TD, - const PowerPCFrameInfo &TFI); +class PPCTargetMachine : public TargetMachine { + PPCInstrInfo InstrInfo; + PPCSubtarget Subtarget; + PPCFrameInfo FrameInfo; + PPCJITInfo JITInfo; public: + PPCTargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS); + + virtual const PPCInstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } + virtual TargetJITInfo *getJITInfo() { return &JITInfo; } virtual const TargetSubtarget *getSubtargetImpl() const{ return &Subtarget; } - - virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType); -}; - -class PPC32TargetMachine : public PowerPCTargetMachine { - PPC32InstrInfo InstrInfo; - PPC32JITInfo JITInfo; - -public: - PPC32TargetMachine(const Module &M, IntrinsicLowering *IL, - const std::string &FS); - virtual const PPC32InstrInfo *getInstrInfo() const { return &InstrInfo; } - virtual const MRegisterInfo *getRegisterInfo() const { + virtual const MRegisterInfo *getRegisterInfo() const { return &InstrInfo.getRegisterInfo(); } - virtual TargetJITInfo *getJITInfo() { - return &JITInfo; - } - static unsigned getJITMatchQuality(); static unsigned getModuleMatchQuality(const Module &M); - + + virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, + CodeGenFileType FileType); + bool addPassesToEmitMachineCode(FunctionPassManager &PM, MachineCodeEmitter &MCE); }; - + } // end namespace llvm #endif Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.31 llvm/lib/Target/PowerPC/README.txt:1.32 --- llvm/lib/Target/PowerPC/README.txt:1.31 Tue Sep 6 10:30:48 2005 +++ llvm/lib/Target/PowerPC/README.txt Sun Oct 16 00:39:50 2005 @@ -105,3 +105,16 @@ Implement Newton-Rhapson method for improving estimate instructions to the correct accuracy, and implementing divide as multiply by reciprocal when it has more than one use. Itanium will want this too. + +===-------------------------------------------------------------------------=== + +int foo(int a, int b) { return a == b ? 16 : 0; } +_foo: + cmpw cr7, r3, r4 + mfcr r2 + rlwinm r2, r2, 31, 31, 31 + slwi r3, r2, 4 + blr + +If we exposed the srl & mask ops after the MFCR that we are doing to select +the correct CR bit, then we could fold the slwi into the rlwinm before it. From lattner at cs.uiuc.edu Sun Oct 16 12:03:34 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 16 Oct 2005 12:03:34 -0500 Subject: [llvm-commits] CVS: llvm/docs/WritingAnLLVMBackend.html Message-ID: <200510161703.MAA20327@zion.cs.uiuc.edu> Changes in directory llvm/docs: WritingAnLLVMBackend.html updated: 1.8 -> 1.9 --- Log message: Update this significantly, mention subtarget and isel generation support. --- Diffs of the changes: (+33 -34) WritingAnLLVMBackend.html | 67 ++++++++++++++++++++++------------------------ 1 files changed, 33 insertions(+), 34 deletions(-) Index: llvm/docs/WritingAnLLVMBackend.html diff -u llvm/docs/WritingAnLLVMBackend.html:1.8 llvm/docs/WritingAnLLVMBackend.html:1.9 --- llvm/docs/WritingAnLLVMBackend.html:1.8 Wed May 18 14:43:25 2005 +++ llvm/docs/WritingAnLLVMBackend.html Sun Oct 16 12:03:22 2005 @@ -68,21 +68,21 @@ implement the following:

      -
    • Describe the register set +
    • Describe the register set.
      • Create a TableGen description of the register set and register classes
      • Implement a subclass of MRegisterInfo
    • -
    • Describe the instruction set +
    • Describe the instruction set.
    • -
    • Describe the target machine +
    • Describe the target machine.
      • Create a TableGen description of the target that describes the pointer size and references the instruction @@ -104,38 +104,37 @@ is the description of your target to appear in -help listing.
    • -
    • Implement the assembly printer for the architecture. Usually, if you have -described the instruction set with the assembly printer generator in mind, that -step can be almost automated.
    • -
    - -

    You also need to write an instruction selector for your platform. The -recommended method is the pattern-matching instruction selector, -examples of which you can see in other targets: -lib/Target/*/*ISelPattern.cpp. The former method for writing -instruction selectors (not recommended for new targets) is evident in -lib/Target/*/*ISelSimple.cpp, which are InstVisitor-based -translators, generating code for an LLVM instruction at a time. Creating an -instruction selector is perhaps the most time-consuming part of creating a -back-end.

    - -

    To create a JIT for your platform:

    - +
  • Implement the assembly printer for the architecture. +
      +
    • Define all of the assembly strings for your target, adding them to the + instructions in your *InstrInfo.td file.
    • +
    • Implement the llvm::AsmPrinter interface.
    • +
    +
  • +
  • Implement an instruction selector for the architecture. +
      +
    • The recommended method is the + pattern-matching DAG-to-DAG instruction selector (for example, see + the PowerPC backend in PPCISelDAGtoDAG.cpp). Parts of instruction + selector creation can be performed by adding patterns to the instructions + in your .td file.
    • +
    +
  • +
  • Optionally, add subtarget support.
      -
    • Create a subclass of TargetJITInfo
    • -
    • Create a machine code emitter that will be used to emit binary code - directly into memory, given MachineInstrs
    • +
    • If your target has multiple subtargets (e.g. variants with different + capabilities), implement the llvm::TargetSubtarget interface + for your architecture. This allows you to add -mcpu= and + -mattr= options.
    • +
    +
  • Optionally, add JIT support. +
      +
    • Create a subclass of TargetJITInfo
    • +
    • Create a machine code emitter that will be used to emit binary code + directly into memory, given MachineInstrs
    • +
    - -

    Note that lib/target/Skeleton is a clean skeleton for a new target, -so you might want to start with that and adapt it for your target, and if you -are wondering how things are done, peek in the X86 or PowerPC target.

    - -

    The Skeleton target is non-functional but provides the basic building blocks -you will need for your endeavor.

    -
  • @@ -253,7 +252,7 @@ Misha Brukman
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/05/18 19:43:25 $ + Last modified: $Date: 2005/10/16 17:03:22 $ From lattner at cs.uiuc.edu Sun Oct 16 12:06:18 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 16 Oct 2005 12:06:18 -0500 Subject: [llvm-commits] CVS: llvm/docs/CodeGenerator.html Message-ID: <200510161706.MAA20463@zion.cs.uiuc.edu> Changes in directory llvm/docs: CodeGenerator.html updated: 1.19 -> 1.20 --- Log message: Add a stub for the TargetSubtarget class. Jim, please fill a blurb in here when you get a chance. --- Diffs of the changes: (+15 -1) CodeGenerator.html | 16 +++++++++++++++- 1 files changed, 15 insertions(+), 1 deletion(-) Index: llvm/docs/CodeGenerator.html diff -u llvm/docs/CodeGenerator.html:1.19 llvm/docs/CodeGenerator.html:1.20 --- llvm/docs/CodeGenerator.html:1.19 Sat Oct 15 19:36:38 2005 +++ llvm/docs/CodeGenerator.html Sun Oct 16 12:06:07 2005 @@ -28,6 +28,7 @@
  • The MRegisterInfo class
  • The TargetInstrInfo class
  • The TargetFrameInfo class
  • +
  • The TargetSubtarget class
  • The TargetJITInfo class
  • @@ -409,6 +410,19 @@ pointer on function entry to the first location where function data (local variables, spill locations) can be stored.

    + + + + +
    +

    + TODO +

    +
    + +
    The TargetJITInfo class @@ -1046,7 +1060,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/10/16 00:36:38 $ + Last modified: $Date: 2005/10/16 17:06:07 $ From lattner at cs.uiuc.edu Sun Oct 16 13:31:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 16 Oct 2005 13:31:19 -0500 Subject: [llvm-commits] CVS: llvm/docs/CodeGenerator.html Message-ID: <200510161831.NAA20779@zion.cs.uiuc.edu> Changes in directory llvm/docs: CodeGenerator.html updated: 1.20 -> 1.21 --- Log message: Fill this out some more. Add description of MBB/MF. Fix some broken links, turn some broken into 's. --- Diffs of the changes: (+114 -32) CodeGenerator.html | 146 +++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 114 insertions(+), 32 deletions(-) Index: llvm/docs/CodeGenerator.html diff -u llvm/docs/CodeGenerator.html:1.20 llvm/docs/CodeGenerator.html:1.21 --- llvm/docs/CodeGenerator.html:1.20 Sun Oct 16 12:06:07 2005 +++ llvm/docs/CodeGenerator.html Sun Oct 16 13:31:08 2005 @@ -35,6 +35,9 @@
  • Machine code description classes
  • Target-independent code generation algorithms @@ -50,14 +53,19 @@
  • SelectionDAG Optimization Phase: the DAG Combiner
  • SelectionDAG Select Phase
  • -
  • SelectionDAG Scheduling and Emission +
  • SelectionDAG Scheduling and Formation Phase
  • Future directions for the SelectionDAG
  • +
  • Code Emission +
  • -
  • Target description implementations +
  • Target-specific Implementation Notes @@ -163,7 +171,7 @@

    Important Note: For historical reasons, the LLVM SparcV9 code generator uses almost entirely different code paths than described in this document. For this reason, there are some deprecated interfaces (such as -TargetRegInfo and TargetSchedInfo), which are only used by the +TargetSchedInfo), which are only used by the V9 backend and should not be used by any other targets. Also, all code in the lib/Target/SparcV9 directory and subdirectories should be considered deprecated, and should not be used as the basis for future code generator work. @@ -185,36 +193,44 @@ generation in this model is divided into the following stages:

      -
    1. Instruction Selection - Determining an -efficient implementation of the input LLVM code in the target instruction set. +
    2. Instruction Selection - This phase +determines an efficient way to express the input LLVM code in the target +instruction set. This stage produces the initial code for the program in the target instruction set, then makes use of virtual registers in SSA form and physical registers that represent any required register assignments due to target constraints or calling -conventions.
    3. +conventions. This step turns the LLVM code into a DAG of target +instructions. + +
    4. Scheduling and Formation - This +phase takes the DAG of target instructions produced by the instruction selection +phase, determines an ordering of the instructions, then emits the instructions +as MachineInstrs with that ordering. +
    5. SSA-based Machine Code Optimizations - This optional stage consists of a series of machine-code optimizations that operate on the SSA-form produced by the instruction selector. Optimizations -like modulo-scheduling, normal scheduling, or peephole optimization work here. +like modulo-scheduling or peephole optimization work here.
    6. -
    7. Register Allocation - The +
    8. Register Allocation - The target code is transformed from an infinite virtual register file in SSA form to the concrete register file used by the target. This phase introduces spill code and eliminates all virtual register references from the program.
    9. -
    10. Prolog/Epilog Code Insertion - Once the +
    11. Prolog/Epilog Code Insertion - Once the machine code has been generated for the function and the amount of stack space required is known (used for LLVM alloca's and spill slots), the prolog and epilog code for the function can be inserted and "abstract stack location references" can be eliminated. This stage is responsible for implementing optimizations like frame-pointer elimination and stack packing.
    12. -
    13. Late Machine Code Optimizations - Optimizations +
    14. Late Machine Code Optimizations - Optimizations that operate on "final" machine code can go here, such as spill code scheduling and peephole optimizations.
    15. -
    16. Code Emission - The final stage actually +
    17. Code Emission - The final stage actually puts out the code for the current function, either in the target assembler format or in machine code.
    18. @@ -259,6 +275,16 @@ repetition.

      +

      As LLVM continues to be developed and refined, we plan to move more and more +of the target description to be in .td form. Doing so gives us a +number of advantages. The most important is that it makes it easier to port +LLVM, because it reduces the amount of C++ code that has to be written and the +surface area of the code generator that needs to be understood before someone +can get in an get something working. Second, it is also important to us because +it makes it easier to change things: in particular, if tables and other things +are all emitted by tblgen, we only need to change one place (tblgen) to update +all of the targets to a new interface.

      +
  • @@ -274,8 +300,7 @@ target machine; independent of any particular client. These classes are designed to capture the abstract properties of the target (such as the instructions and registers it has), and do not incorporate any particular pieces -of code generation algorithms. These interfaces do not take interference graphs -as inputs or other algorithm-specific data structures.

    +of code generation algorithms.

    All of the target description classes (except the TargetData class) are designed to be subclassed by @@ -315,8 +340,8 @@

    The TargetData class is the only required target description class, -and it is the only class that is not extensible. You cannot derived a new -class from it. TargetData specifies information about how the target +and it is the only class that is not extensible (you cannot derived a new +class from it). TargetData specifies information about how the target lays out memory for structures, the alignment requirements for various data types, the size of pointers in the target, and whether the target is little-endian or big-endian.

    @@ -333,18 +358,16 @@

    The TargetLowering class is used by SelectionDAG based instruction selectors primarily to describe how LLVM code should be lowered to SelectionDAG operations. Among other things, this class indicates: -

    • an initial register class to use for various ValueTypes,
    • -
    • which operations are natively supported by the target machine,
    • -
    • the return type of setcc operations, and
    • -
    • the type to use for shift amounts, etc
    • . +
      • an initial register class to use for various ValueTypes
      • +
      • which operations are natively supported by the target machine
      • +
      • the return type of setcc operations
      • +
      • the type to use for shift amounts
      • +
      • various high-level characteristics, like whether it is profitable to turn + division by a constant into a multiplication sequence
    - - - -
    The MRegisterInfo class @@ -359,7 +382,7 @@

    Registers in the code generator are represented in the code generator by unsigned numbers. Physical registers (those that actually exist in the target description) are unique small numbers, and virtual registers are generally -large.

    +large. Note that register #0 is reserved as a flag value.

    Each register in the processor description has an associated TargetRegisterDesc entry, which provides a textual name for the register @@ -438,7 +461,8 @@

    At the high-level, LLVM code is translated to a machine specific representation -formed out of MachineFunction, MachineBasicBlock, and MachineFunction, +MachineBasicBlock, and MachineInstr instances (defined in include/llvm/CodeGen). This representation is completely target agnostic, representing instructions in their most abstract form: an opcode and a @@ -624,6 +648,43 @@

    + + + +
    + +

    The MachineBasicBlock class contains a list of machine instructions +(MachineInstr instances). It roughly corresponds to +the LLVM code input to the instruction selector, but there can be a one-to-many +mapping (i.e. one LLVM basic block can map to multiple machine basic blocks). +The MachineBasicBlock class has a "getBasicBlock" method, which returns +the LLVM basic block that it comes from. +

    + +
    + + + + +
    + +

    The MachineFunction class contains a list of machine basic blocks +(MachineBasicBlock instances). It corresponds +one-to-one with the LLVM function input to the instruction selector. In +addition to a list of basic blocks, the MachineFunction contains a +the MachineConstantPool, MachineFrameInfo, MachineFunctionInfo, +SSARegMap, and a set of live in and live out registers for the function. See +MachineFunction.h for more information. +

    + +
    + + +
    Target-independent code generation algorithms @@ -633,7 +694,7 @@

    This section documents the phases described in the high-level design of the code generator. It +href="#high-level-design">high-level design of the code generator. It explains how they work and some of the rationale behind their design.

    @@ -755,7 +816,7 @@ the target instruction selector matches the DAG operations to target instructions. This process translates the target-independent input DAG into another DAG of target instructions. -
  • SelectionDAG Scheduling and Emission +
  • SelectionDAG Scheduling and Formation - The last phase assigns a linear order to the instructions in the target-instruction DAG and emits them into the MachineFunction being compiled. This step uses traditional prepass scheduling techniques.
  • @@ -892,7 +953,7 @@
    @@ -944,12 +1005,33 @@

    To Be Written

    + + + + +
    + +
    + + + + + +
    +

    For the JIT or .o file writer

    +
    + + @@ -995,7 +1077,7 @@
  • i386-unknown-freebsd5.3 - FreeBSD 5.3
  • i686-pc-cygwin - Cygwin on Win32
  • i686-pc-mingw32 - MingW on Win32
  • -
  • i686-apple-darwin* - Apple Darwin
  • +
  • i686-apple-darwin* - Apple Darwin on X86
  • @@ -1060,7 +1142,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/10/16 17:06:07 $ + Last modified: $Date: 2005/10/16 18:31:08 $ From lattner at cs.uiuc.edu Sun Oct 16 15:02:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 16 Oct 2005 15:02:31 -0500 Subject: [llvm-commits] CVS: llvm/docs/CodeGenerator.html Message-ID: <200510162002.PAA21336@zion.cs.uiuc.edu> Changes in directory llvm/docs: CodeGenerator.html updated: 1.21 -> 1.22 --- Log message: Add a bunch of info about the isel autogenerator. Review appreciated! --- Diffs of the changes: (+169 -34) CodeGenerator.html | 203 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 169 insertions(+), 34 deletions(-) Index: llvm/docs/CodeGenerator.html diff -u llvm/docs/CodeGenerator.html:1.21 llvm/docs/CodeGenerator.html:1.22 --- llvm/docs/CodeGenerator.html:1.21 Sun Oct 16 13:31:08 2005 +++ llvm/docs/CodeGenerator.html Sun Oct 16 15:02:19 2005 @@ -731,8 +731,10 @@ The SelectionDAG provides an abstraction for code representation in a way that is amenable to instruction selection using automatic techniques (e.g. dynamic-programming based optimal pattern matching selectors), It is also -well suited to other phases of code generation; in particular, instruction scheduling. Additionally, the SelectionDAG provides a host representation where a -large variety of very-low-level (but target-independent) +well suited to other phases of code generation; in particular, +instruction scheduling (SelectionDAG's are very close to scheduling DAGs +post-selection). Additionally, the SelectionDAG provides a host representation +where a large variety of very-low-level (but target-independent) optimizations may be performed: ones which require extensive information about the instructions efficiently supported by the target. @@ -741,11 +743,10 @@

    The SelectionDAG is a Directed-Acyclic-Graph whose nodes are instances of the SDNode class. The primary payload of the SDNode is its -operation code (Opcode) that indicates what operation the node performs. +operation code (Opcode) that indicates what operation the node performs and +the operands to the operation. The various operation node types are described at the top of the -include/llvm/CodeGen/SelectionDAGNodes.h file. Depending on the -operation, nodes may contain additional information (e.g. the condition code -for a SETCC node) contained in a derived class.

    +include/llvm/CodeGen/SelectionDAGNodes.h file.

    Although most operations define a single value, each node in the graph may define multiple values. For example, a combined div/rem operation will define @@ -779,8 +780,10 @@

    One important concept for SelectionDAGs is the notion of a "legal" vs. "illegal" DAG. A legal DAG for a target is one that only uses supported operations and -supported types. On PowerPC, for example, a DAG with any values of i1, i8, i16, -or i64 type would be illegal. The legalize +supported types. On a 32-bit PowerPC, for example, a DAG with any values of i1, +i8, i16, +or i64 type would be illegal, as would a DAG that uses a SREM or UREM operation. +The legalize phase is responsible for turning an illegal DAG into a legal DAG.

    @@ -841,7 +844,8 @@ to the SelectionDAG as possible. This pass is mostly hard-coded (e.g. an LLVM add turns into an SDNode add while a geteelementptr is expanded into the obvious arithmetic). This pass requires target-specific hooks to lower calls and -returns, varargs, etc. For these features, the TargetLowering interface is +returns, varargs, etc. For these features, the TargetLowering interface is used.

    @@ -860,34 +864,41 @@
    1. Convert values of unsupported types to values of supported types.

      -

      There are two main ways of doing this: promoting a small type to a larger - type (e.g. f32 -> f64, or i16 -> i32), and breaking up large - integer types - to smaller ones (e.g. implementing i64 with i32 operations where - possible). Type conversions can insert sign and zero extensions as +

      There are two main ways of doing this: converting small types to + larger types ("promoting"), and breaking up large integer types + into smaller ones ("expanding"). For example, a target might require + that all f32 values are promoted to f64 and that all i1/i8/i16 values + are promoted to i32. The same target might require that all i64 values + be expanded into i32 values. These changes can insert sign and zero + extensions as needed to make sure that the final code has the same behavior as the input.

      +

      A target implementation tells the legalizer which types are supported + (and which register class to use for them) by calling the + "addRegisterClass" method in its TargetLowering constructor.

    2. -
    3. Eliminate operations that are not supported by the target in a supported - type.

      -

      Targets often have wierd constraints, such as not supporting every +

    4. Eliminate operations that are not supported by the target.

      +

      Targets often have weird constraints, such as not supporting every operation on every supported datatype (e.g. X86 does not support byte - conditional moves). Legalize takes care of either open-coding another - sequence of operations to emulate the operation (this is known as - expansion), promoting to a larger type that supports the operation + conditional moves and PowerPC does not support sign-extending loads from + a 16-bit memory location). Legalize takes care by open-coding + another sequence of operations to emulate the operation ("expansion"), by + promoting to a larger type that supports the operation (promotion), or using a target-specific hook to implement the - legalization.

      + legalization (custom).

      +

      A target implementation tells the legalizer which operations are not + supported (and which of the above three actions to take) by calling the + "setOperationAction" method in its TargetLowering constructor.

    -Instead of using a Legalize pass, we could require that every target-specific -selector supports and expands every -operator and type even if they are not supported and may require many -instructions to implement (in fact, this is the approach taken by the -"simple" selectors). However, using a Legalize pass allows all of the -cannonicalization patterns to be shared across targets which makes it very +Prior to the existance of the Legalize pass, we required that every +target selector supported and handled every +operator and type even if they are not natively supported. The introduction of +the Legalize phase allows all of the +cannonicalization patterns to be shared across targets, and makes it very easy to optimize the cannonicalized code because it is still in the form of a DAG.

    @@ -908,8 +919,8 @@ of the pass allows the initial code to be cleaned up (e.g. performing optimizations that depend on knowing that the operators have restricted type inputs). The second run of the pass cleans up the messy code generated by the -Legalize pass, allowing Legalize to be very simple since it can ignore many -special cases. +Legalize pass, which allows Legalize to be very simple (it can focus on making +code legal instead of focusing on generating good and legal code).

    @@ -944,10 +955,134 @@

    The Select phase is the bulk of the target-specific code for instruction -selection. This phase takes a legal SelectionDAG as input, and does simple -pattern matching on the DAG to generate code. In time, the Select phase will -be automatically generated from the target's InstrInfo.td file, which is why we -want to make the Select phase as simple and mechanical as possible.

    +selection. This phase takes a legal SelectionDAG as input, +pattern matches the instructions supported by the target to this DAG, and +produces a new DAG of target code. For example, consider the following LLVM +fragment:

    + +
    +   %t1 = add float %W, %X
    +   %t2 = mul float %t1, %Y
    +   %t3 = add float %t2, %Z
    +
    + +

    This LLVM code corresponds to a SelectionDAG that looks basically like this: +

    + +
    +  (fadd:f32 (fmul:f32 (fadd:f32 W, X), Y), Z)
    +
    + +

    If a target supports floating pointer multiple-and-add (FMA) operations, one +of the adds can be merged with the multiply. On the PowerPC, for example, the +output of the instruction selector might look like this DAG:

    + +
    +  (FMADDS (FADDS W, X), Y, Z)
    +
    + +

    +The FMADDS instruction is a ternary instruction that multiplies its first two +operands and adds the third (as single-precision floating-point numbers). The +FADDS instruction is a simple binary single-precision add instruction. To +perform this pattern match, the PowerPC backend includes the following +instruction definitions: +

    + +
    +def FMADDS : AForm_1<59, 29,
    +                    (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
    +                    "fmadds $FRT, $FRA, $FRC, $FRB",
    +                    [(set F4RC:$FRT, (fadd (fmul F4RC:$FRA, F4RC:$FRC),
    +                                           F4RC:$FRB))]>;
    +def FADDS : AForm_2<59, 21,
    +                    (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
    +                    "fadds $FRT, $FRA, $FRB",
    +                    [(set F4RC:$FRT, (fadd F4RC:$FRA, F4RC:$FRB))]>;
    +
    + +

    The portion of the instruction definition in bold indicates the pattern used +to match the instruction. The DAG operators (like fmul/fadd) +are defined in the lib/Target/TargetSelectionDAG.td file. +"F4RC" is the register class of the input and result values.

    + +

    The TableGen DAG instruction selector generator reads the instruction +patterns in the .td and automatically builds parts of the pattern matching code +for your target. It has the following strengths:

    + +
      +
    • At compiler-compiler time, it analyzes your instruction patterns and tells + you if things are legal or not.
    • +
    • It can handle arbitrary constraints on operands for the pattern match. In + particular, it is straight forward to say things like "match any immediate + that is a 13-bit sign-extended value". For examples, see the + immSExt16 and related tblgen classes in the PowerPC backend.
    • +
    • It knows several important identities for the patterns defined. For + example, it knows that addition is commutative, so it allows the + FMADDS pattern above to match "(fadd X, (fmul Y, Z))" as + well as "(fadd (fmul X, Y), Z)", without the target author having + to specially handle this case.
    • +
    • It has a full strength type-inferencing system. In particular, you should + rarely have to explicitly tell the system what type parts of your patterns + are. In the FMADDS case above, we didn't have to tell tblgen that all of + the nodes in the pattern are of type 'f32'. It was able to infer and + propagate this knowledge from the fact that F4RC has type 'f32'.
    • +
    • Targets can define their own (and rely on built-in) "pattern fragments". + Pattern fragments are chunks of reusable patterns that get inlined into your + patterns during compiler-compiler time. For example, the integer "(not x)" + operation is actually defined as a pattern fragment that expands as + "(xor x, -1)", since the SelectionDAG does not have a native 'not' + operation. Targets can define their own short-hand fragments as they see + fit. See the definition of 'not' and 'ineg' for examples.
    • +
    • In addition to instructions, targets can specify arbitrary patterns that + map to one or more instructions, using the 'Pat' definition. For example, + the PowerPC has no way of loading an arbitrary integer immediate into a + register in one instruction. To tell tblgen how to do this, it defines: + +
      +    // Arbitrary immediate support.  Implement in terms of LIS/ORI.
      +    def : Pat<(i32 imm:$imm),
      +              (ORI (LIS (HI16 imm:$imm)), (LO16 imm:$imm))>;
      +    
      + + If none of the single-instruction patterns for loading an immediate into a + register match, this will be used. This rule says "match an arbitrary i32 + immediate, turning it into an ORI ('or a 16-bit immediate') and an LIS + ('load 16-bit immediate, where the immediate is shifted to the left 16 + bits') instruction". To make this work, the LO16/HI16 node transformations + are used to manipulate the input immediate (in this case, take the high or + low 16-bits of the immediate). +
    • +
    • While the system does automate a lot, it still allows you to write custom + C++ code to match special cases, in case there is something that is hard + to express.
    • +
    + +

    +While it has many strengths, the system currently has some limitations, +primarily because it is a work in progress and is not yet finished: +

    + +
      +
    • Overall, there is no way to define or match SelectionDAG nodes that define + multiple values (e.g. ADD_PARTS, LOAD, CALL, etc). This is the biggest + reason that you currently still have to write custom C++ code for + your instruction selector.
    • +
    • There is no great way to support match complex addressing modes yet. In the + future, we will extend pattern fragments to allow them to define multiple + values (e.g. the four operands of the X86 addressing + mode). In addition, we'll extend fragments so that a fragment can match + multiple different patterns.
    • +
    • We don't automatically infer flags like isStore/isLoad yet.
    • +
    • We don't automatically generate the set of supported registers and + operations for the Legalizer yet.
    • +
    • We don't have a way of tying in custom legalized nodes yet.
    • + + +

      Despite these limitations, the instruction selector generator is still quite +useful for most of the binary and logical operations in typical instruction +sets. If you run into any problems or can't figure out how to do something, +please let Chris know!

    @@ -1142,7 +1277,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/10/16 18:31:08 $ + Last modified: $Date: 2005/10/16 20:02:19 $ From lattner at cs.uiuc.edu Sun Oct 16 20:07:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 16 Oct 2005 20:07:23 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200510170107.UAA08351@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.43 -> 1.44 --- Log message: add a trivial fold --- 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.43 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.44 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.43 Sat Oct 15 17:35:40 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sun Oct 16 20:07:11 2005 @@ -532,6 +532,10 @@ ConstantSDNode *N0C = dyn_cast(N0.Val); ConstantSDNode *N1C = dyn_cast(N1.Val); + // fold (sub x, x) -> 0 + if (N0 == N1) + return DAG.getConstant(0, N->getValueType(0)); + // fold (sub c1, c2) -> c1-c2 if (N0C && N1C) return DAG.getConstant(N0C->getValue() - N1C->getValue(), From lattner at cs.uiuc.edu Sun Oct 16 20:36:35 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 16 Oct 2005 20:36:35 -0500 Subject: [llvm-commits] CVS: llvm/docs/ProgrammersManual.html Message-ID: <200510170136.UAA13294@zion.cs.uiuc.edu> Changes in directory llvm/docs: ProgrammersManual.html updated: 1.86 -> 1.87 --- Log message: Add notes about MF.viewCFG() and friends. --- Diffs of the changes: (+40 -1) ProgrammersManual.html | 41 ++++++++++++++++++++++++++++++++++++++++- 1 files changed, 40 insertions(+), 1 deletion(-) Index: llvm/docs/ProgrammersManual.html diff -u llvm/docs/ProgrammersManual.html:1.86 llvm/docs/ProgrammersManual.html:1.87 --- llvm/docs/ProgrammersManual.html:1.86 Tue May 10 17:06:41 2005 +++ llvm/docs/ProgrammersManual.html Sun Oct 16 20:36:23 2005 @@ -41,6 +41,7 @@
  • The InstVisitor template
  • The general graph API --> +
  • Viewing graphs while debugging code
  • Helpful Hints for Common Operations @@ -491,6 +492,44 @@ + + + +
    + +

    Several of the important data structures in LLVM are graphs: for example +CFGs made out of LLVM BasicBlocks, CFGs made out of +LLVM MachineBasicBlocks, and +Instruction Selection +DAGs. In many cases, while debugging various parts of the compiler, it is +nice to instantly visualize these graphs.

    + +

    LLVM provides several callbacks that are available in a debug build to do +exactly that. If you call the Function::viewCFG() method, for example, +the current LLVM tool will pop up a window containing the CFG for the function +where each basic block is a node in the graph, and each node contains the +instructions in the block. Similarly, there also exists +Function::viewCFGOnly() (does not include the instructions), the +MachineFunction::viewCFG() and MachineFunction::viewCFGOnly(), +and the SelectionDAG::viewGraph() methods. Within GDB, for example, +you can usually use something like "call DAG.viewGraph()" to pop +up a window. Alternatively, you can sprinkle calls to these functions in your +code in places you want to debug.

    + +

    Getting this to work requires a small amount of configuration. On Unix +systems with X11, install the graphviz +toolkit, and make sure 'dot' and 'gv' are in your path. If you are running on +Mac OS/X, download and install the Mac OS/X Graphviz program, and add +/Applications/Graphviz.app/Contents/MacOS/ (or whereever you install +it) to your path. Once in your system and path are set up, rerun the LLVM +configure script and rebuild LLVM to enable this functionality.

    + +
    + +
    Helpful Hints for Common Operations @@ -2236,7 +2275,7 @@ Dinakar Dhurjati and Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/05/10 22:06:41 $ + Last modified: $Date: 2005/10/17 01:36:23 $ From lattner at cs.uiuc.edu Sun Oct 16 20:40:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 16 Oct 2005 20:40:44 -0500 Subject: [llvm-commits] CVS: llvm/docs/CodeGenerator.html Message-ID: <200510170140.UAA15127@zion.cs.uiuc.edu> Changes in directory llvm/docs: CodeGenerator.html updated: 1.22 -> 1.23 --- Log message: Document -view-isel-dags and -view-sched-dags --- Diffs of the changes: (+10 -1) CodeGenerator.html | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletion(-) Index: llvm/docs/CodeGenerator.html diff -u llvm/docs/CodeGenerator.html:1.22 llvm/docs/CodeGenerator.html:1.23 --- llvm/docs/CodeGenerator.html:1.22 Sun Oct 16 15:02:19 2005 +++ llvm/docs/CodeGenerator.html Sun Oct 16 20:40:33 2005 @@ -828,6 +828,15 @@

    After all of these steps are complete, the SelectionDAG is destroyed and the rest of the code generation passes are run.

    +

    One great way to visualize what is going on here is to take advantage of a +few LLC command line options. In particular, the -view-isel-dags +option pops up a window with the SelectionDAG input to the Select phase for all +of the code compiled (if you only get errors printed to the console while using +this, you probably need to configure +your system to add support for it). The -view-sched-dags option +views the SelectionDAG output from the Select phase and input to the Scheduler +phase. +

    @@ -1277,7 +1286,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/10/16 20:02:19 $ + Last modified: $Date: 2005/10/17 01:40:33 $ From lattner at cs.uiuc.edu Sun Oct 16 22:09:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 16 Oct 2005 22:09:42 -0500 Subject: [llvm-commits] CVS: llvm/docs/CodeGenerator.html Message-ID: <200510170309.WAA16567@zion.cs.uiuc.edu> Changes in directory llvm/docs: CodeGenerator.html updated: 1.23 -> 1.24 --- Log message: Feedback from Nate. --- Diffs of the changes: (+9 -2) CodeGenerator.html | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-) Index: llvm/docs/CodeGenerator.html diff -u llvm/docs/CodeGenerator.html:1.23 llvm/docs/CodeGenerator.html:1.24 --- llvm/docs/CodeGenerator.html:1.23 Sun Oct 16 20:40:33 2005 +++ llvm/docs/CodeGenerator.html Sun Oct 16 22:09:31 2005 @@ -205,7 +205,10 @@
  • Scheduling and Formation - This phase takes the DAG of target instructions produced by the instruction selection phase, determines an ordering of the instructions, then emits the instructions -as MachineInstrs with that ordering. +as MachineInstrs with that ordering. Note +that we describe this in the instruction selection +section because it operates on a SelectionDAG.
  • SSA-based Machine Code Optimizations - This @@ -1110,6 +1113,10 @@ Selection DAG is destroyed.

    +

    Note that this phase is logically seperate from the instruction selection +phase, but is tied to it closely in the code because it operates on +SelectionDAGs.

    + @@ -1286,7 +1293,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/10/17 01:40:33 $ + Last modified: $Date: 2005/10/17 03:09:31 $ From lattner at cs.uiuc.edu Sun Oct 16 23:18:52 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 16 Oct 2005 23:18:52 -0500 Subject: [llvm-commits] CVS: llvm/docs/CodeGenerator.html Message-ID: <200510170418.XAA22687@zion.cs.uiuc.edu> Changes in directory llvm/docs: CodeGenerator.html updated: 1.24 -> 1.25 --- Log message: fix some grammar-o's I noticed --- Diffs of the changes: (+8 -8) CodeGenerator.html | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) Index: llvm/docs/CodeGenerator.html diff -u llvm/docs/CodeGenerator.html:1.24 llvm/docs/CodeGenerator.html:1.25 --- llvm/docs/CodeGenerator.html:1.24 Sun Oct 16 22:09:31 2005 +++ llvm/docs/CodeGenerator.html Sun Oct 16 23:18:41 2005 @@ -985,7 +985,7 @@ (fadd:f32 (fmul:f32 (fadd:f32 W, X), Y), Z) -

    If a target supports floating pointer multiple-and-add (FMA) operations, one +

    If a target supports floating pointer multiply-and-add (FMA) operations, one of the adds can be merged with the multiply. On the PowerPC, for example, the output of the instruction selector might look like this DAG:

    @@ -1024,9 +1024,9 @@
    • At compiler-compiler time, it analyzes your instruction patterns and tells - you if things are legal or not.
    • + you if your patterns make sense or not.
    • It can handle arbitrary constraints on operands for the pattern match. In - particular, it is straight forward to say things like "match any immediate + particular, it is straight-forward to say things like "match any immediate that is a 13-bit sign-extended value". For examples, see the immSExt16 and related tblgen classes in the PowerPC backend.
    • It knows several important identities for the patterns defined. For @@ -1034,7 +1034,7 @@ FMADDS pattern above to match "(fadd X, (fmul Y, Z))" as well as "(fadd (fmul X, Y), Z)", without the target author having to specially handle this case.
    • -
    • It has a full strength type-inferencing system. In particular, you should +
    • It has a full-featured type-inferencing system. In particular, you should rarely have to explicitly tell the system what type parts of your patterns are. In the FMADDS case above, we didn't have to tell tblgen that all of the nodes in the pattern are of type 'f32'. It was able to infer and @@ -1047,8 +1047,8 @@ operation. Targets can define their own short-hand fragments as they see fit. See the definition of 'not' and 'ineg' for examples.
    • In addition to instructions, targets can specify arbitrary patterns that - map to one or more instructions, using the 'Pat' definition. For example, - the PowerPC has no way of loading an arbitrary integer immediate into a + map to one or more instructions, using the 'Pat' class. For example, + the PowerPC has no way to load an arbitrary integer immediate into a register in one instruction. To tell tblgen how to do this, it defines:
      @@ -1089,7 +1089,7 @@
       
    • We don't automatically generate the set of supported registers and operations for the Legalizer yet.
    • We don't have a way of tying in custom legalized nodes yet.
    • -
    • +

    Despite these limitations, the instruction selector generator is still quite useful for most of the binary and logical operations in typical instruction @@ -1293,7 +1293,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/10/17 03:09:31 $ + Last modified: $Date: 2005/10/17 04:18:41 $