From evan.cheng at apple.com Mon Oct 8 01:59:30 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 08 Oct 2007 06:59:30 -0000 Subject: [llvm-commits] [llvm] r42742 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200710080659.l986xUeo001806@zion.cs.uiuc.edu> Author: evancheng Date: Mon Oct 8 01:59:30 2007 New Revision: 42742 URL: http://llvm.org/viewvc/llvm-project?rev=42742&view=rev Log: Kill cycle of an live range is always the last use index + 1. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=42742&r1=42741&r2=42742&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Mon Oct 8 01:59:30 2007 @@ -449,7 +449,7 @@ nI.weight = HUGE_VALF; if (HasUse) { - LiveRange LR(getLoadIndex(index), getUseIndex(index), + LiveRange LR(getLoadIndex(index), getUseIndex(index)+1, nI.getNextValue(~0U, 0, VNInfoAllocator)); DOUT << " +" << LR; nI.addRange(LR); From resistor at mac.com Mon Oct 8 02:44:39 2007 From: resistor at mac.com (Owen Anderson) Date: Mon, 08 Oct 2007 07:44:39 -0000 Subject: [llvm-commits] [llvm] r42743 - in /llvm/trunk: include/llvm/Analysis/Dominators.h lib/VMCore/Dominators.cpp Message-ID: <200710080744.l987idjU010447@zion.cs.uiuc.edu> Author: resistor Date: Mon Oct 8 02:44:39 2007 New Revision: 42743 URL: http://llvm.org/viewvc/llvm-project?rev=42743&view=rev Log: Begin the process of allowing DomTree on MBB's. Step One: template DomTreeNode by making it a typedef of a templated DomTreeNodeBase. Modified: llvm/trunk/include/llvm/Analysis/Dominators.h llvm/trunk/lib/VMCore/Dominators.cpp Modified: llvm/trunk/include/llvm/Analysis/Dominators.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=42743&r1=42742&r2=42743&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/Dominators.h (original) +++ llvm/trunk/include/llvm/Analysis/Dominators.h Mon Oct 8 02:44:39 2007 @@ -22,6 +22,7 @@ #define LLVM_ANALYSIS_DOMINATORS_H #include "llvm/Pass.h" +#include #include #include "llvm/ADT/DenseMap.h" @@ -59,32 +60,56 @@ // DomTreeNode - Dominator Tree Node class DominatorTreeBase; class PostDominatorTree; -class DomTreeNode { - BasicBlock *TheBB; - DomTreeNode *IDom; - std::vector Children; +class MachineBasicBlock; + +template +class DomTreeNodeBase { + NodeT *TheBB; + DomTreeNodeBase *IDom; + std::vector *> Children; int DFSNumIn, DFSNumOut; friend class DominatorTreeBase; friend class PostDominatorTree; public: - typedef std::vector::iterator iterator; - typedef std::vector::const_iterator const_iterator; + typedef typename std::vector *>::iterator iterator; + typedef typename std::vector *>::const_iterator + const_iterator; iterator begin() { return Children.begin(); } iterator end() { return Children.end(); } const_iterator begin() const { return Children.begin(); } const_iterator end() const { return Children.end(); } - BasicBlock *getBlock() const { return TheBB; } - DomTreeNode *getIDom() const { return IDom; } - const std::vector &getChildren() const { return Children; } + NodeT *getBlock() const { return TheBB; } + DomTreeNodeBase *getIDom() const { return IDom; } + const std::vector*> &getChildren() const { + return Children; + } - DomTreeNode(BasicBlock *BB, DomTreeNode *iDom) + DomTreeNodeBase(NodeT *BB, DomTreeNodeBase *iDom) : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) { } - DomTreeNode *addChild(DomTreeNode *C) { Children.push_back(C); return C; } - void setIDom(DomTreeNode *NewIDom); - + + DomTreeNodeBase *addChild(DomTreeNodeBase *C) { + Children.push_back(C); + return C; + } + + void setIDom(DomTreeNodeBase *NewIDom) { + assert(IDom && "No immediate dominator?"); + if (IDom != NewIDom) { + std::vector*>::iterator I = + std::find(IDom->Children.begin(), IDom->Children.end(), this); + assert(I != IDom->Children.end() && + "Not in immediate dominator children set!"); + // I am no longer your child... + IDom->Children.erase(I); + + // Switch to new dominator + IDom = NewIDom; + IDom->Children.push_back(this); + } + } /// getDFSNumIn/getDFSNumOut - These are an internal implementation detail, do /// not call them. @@ -93,12 +118,15 @@ private: // Return true if this node is dominated by other. Use this only if DFS info // is valid. - bool DominatedBy(const DomTreeNode *other) const { + bool DominatedBy(const DomTreeNodeBase *other) const { return this->DFSNumIn >= other->DFSNumIn && this->DFSNumOut <= other->DFSNumOut; } }; +typedef DomTreeNodeBase DomTreeNode; +typedef DomTreeNodeBase MachineDomTreeNode; + //===----------------------------------------------------------------------===// /// DominatorTree - Calculate the immediate dominator tree for a function. /// @@ -162,7 +190,8 @@ /// properlyDominates - Returns true iff this dominates N and this != N. /// Note that this is not a constant time operation! /// - bool properlyDominates(const DomTreeNode *A, DomTreeNode *B) const { + bool properlyDominates(const DomTreeNode *A, + DomTreeNode *B) const { if (A == 0 || B == 0) return false; return dominatedBySlowTreeWalk(A, B); } @@ -188,7 +217,8 @@ /// dominates - Returns true iff A dominates B. Note that this is not a /// constant time operation! /// - inline bool dominates(const DomTreeNode *A, DomTreeNode *B) { + inline bool dominates(const DomTreeNode *A, + DomTreeNode *B) { if (B == A) return true; // A node trivially dominates itself. @@ -243,7 +273,8 @@ /// changeImmediateDominator - This method is used to update the dominator /// tree information when a node's immediate dominator changes. /// - void changeImmediateDominator(DomTreeNode *N, DomTreeNode *NewIDom) { + void changeImmediateDominator(DomTreeNode *N, + DomTreeNode *NewIDom) { assert(N && NewIDom && "Cannot change null node pointers!"); DFSInfoValid = false; N->setIDom(NewIDom); @@ -334,7 +365,7 @@ /// DominatorTree GraphTraits specialization so the DominatorTree can be /// iterable by generic graph iterators. /// -template <> struct GraphTraits { +template <> struct GraphTraits { typedef DomTreeNode NodeType; typedef NodeType::iterator ChildIteratorType; @@ -350,7 +381,7 @@ }; template <> struct GraphTraits - : public GraphTraits { + : public GraphTraits { static NodeType *getEntryNode(DominatorTree *DT) { return DT->getRootNode(); } Modified: llvm/trunk/lib/VMCore/Dominators.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Dominators.cpp?rev=42743&r1=42742&r2=42743&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Dominators.cpp (original) +++ llvm/trunk/lib/VMCore/Dominators.cpp Mon Oct 8 02:44:39 2007 @@ -276,22 +276,6 @@ return NULL; } -void DomTreeNode::setIDom(DomTreeNode *NewIDom) { - assert(IDom && "No immediate dominator?"); - if (IDom != NewIDom) { - std::vector::iterator I = - std::find(IDom->Children.begin(), IDom->Children.end(), this); - assert(I != IDom->Children.end() && - "Not in immediate dominator children set!"); - // I am no longer your child... - IDom->Children.erase(I); - - // Switch to new dominator - IDom = NewIDom; - IDom->Children.push_back(this); - } -} - static std::ostream &operator<<(std::ostream &o, const DomTreeNode *Node) { if (Node->getBlock()) WriteAsOperand(o, Node->getBlock(), false); From gordonhenriksen at mac.com Mon Oct 8 07:17:00 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Mon, 08 Oct 2007 12:17:00 -0000 Subject: [llvm-commits] [llvm] r42744 - /llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c Message-ID: <200710081217.l98CH0OX019405@zion.cs.uiuc.edu> Author: gordon Date: Mon Oct 8 07:16:59 2007 New Revision: 42744 URL: http://llvm.org/viewvc/llvm-project?rev=42744&view=rev Log: Fixed downrev Ocaml compatibility. Modified: llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c Modified: llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c?rev=42744&r1=42743&r2=42744&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c Mon Oct 8 07:16:59 2007 @@ -416,7 +416,7 @@ CAMLparam1(Name); LLVMValueRef GlobalVar; if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) { - value Option = caml_alloc(1, 1); + value Option = alloc(1, 1); Field(Option, 0) = (value) GlobalVar; CAMLreturn(Option); } @@ -493,7 +493,7 @@ CAMLparam1(Name); LLVMValueRef Fn; if ((Fn = LLVMGetNamedFunction(M, String_val(Name)))) { - value Option = caml_alloc(1, 1); + value Option = alloc(1, 1); Field(Option, 0) = (value) Fn; CAMLreturn(Option); } From neil at daikokuya.co.uk Mon Oct 8 08:47:13 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Mon, 08 Oct 2007 13:47:13 -0000 Subject: [llvm-commits] [llvm] r42745 - in /llvm/trunk: include/llvm/ADT/APInt.h lib/Support/APInt.cpp Message-ID: <200710081347.l98DlD1v022846@zion.cs.uiuc.edu> Author: neil Date: Mon Oct 8 08:47:12 2007 New Revision: 42745 URL: http://llvm.org/viewvc/llvm-project?rev=42745&view=rev Log: Add a new function tcExtract for extracting a bignum from an arbitrary range of bits embedded in the middle of another bignum. This kind of operation is desirable in many cases of software floating point, e.g. converting bignum integers to floating point numbers of fixed precision (you want to extract the precision most significant bits). Elsewhere, add an assertion, and exit the shift functions early if the shift count is zero. Modified: llvm/trunk/include/llvm/ADT/APInt.h llvm/trunk/lib/Support/APInt.cpp Modified: llvm/trunk/include/llvm/ADT/APInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=42745&r1=42744&r2=42745&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APInt.h (original) +++ llvm/trunk/include/llvm/ADT/APInt.h Mon Oct 8 08:47:12 2007 @@ -1069,6 +1069,13 @@ /// Extract the given bit of a bignum; returns 0 or 1. Zero-based. static int tcExtractBit(const integerPart *, unsigned int bit); + /// Copy the bit vector of width srcBITS from SRC, starting at bit + /// srcLSB, to DST, of dstCOUNT parts, such that the bit srcLSB + /// becomes the least significant bit of DST. All high bits above + /// srcBITS in DST are zero-filled. + static void tcExtract(integerPart *, unsigned int dstCount, const integerPart *, + unsigned int srcBits, unsigned int srcLSB); + /// Set the given bit of a bignum. Zero-based. static void tcSetBit(integerPart *, unsigned int bit); Modified: llvm/trunk/lib/Support/APInt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=42745&r1=42744&r2=42745&view=diff ============================================================================== --- llvm/trunk/lib/Support/APInt.cpp (original) +++ llvm/trunk/lib/Support/APInt.cpp Mon Oct 8 08:47:12 2007 @@ -2101,6 +2101,8 @@ { unsigned int i; + assert (parts > 0); + dst[0] = part; for(i = 1; i < parts; i++) dst[i] = 0; @@ -2182,6 +2184,42 @@ return -1U; } +/* Copy the bit vector of width srcBITS from SRC, starting at bit + srcLSB, to DST, of dstCOUNT parts, such that the bit srcLSB becomes + the least significant bit of DST. All high bits above srcBITS in + DST are zero-filled. */ +void +APInt::tcExtract(integerPart *dst, unsigned int dstCount, const integerPart *src, + unsigned int srcBits, unsigned int srcLSB) +{ + unsigned int firstSrcPart, dstParts, shift, n; + + dstParts = (srcBits + integerPartWidth - 1) / integerPartWidth; + assert (dstParts <= dstCount); + + firstSrcPart = srcLSB / integerPartWidth; + tcAssign (dst, src + firstSrcPart, dstParts); + + shift = srcLSB % integerPartWidth; + tcShiftRight (dst, dstParts, shift); + + /* We now have (dstParts * integerPartWidth - shift) bits from SRC + in DST. If this is less that srcBits, append the rest, else + clear the high bits. */ + n = dstParts * integerPartWidth - shift; + if (n < srcBits) { + integerPart mask = lowBitMask (srcBits - n); + dst[dstParts - 1] |= ((src[firstSrcPart + dstParts] & mask) + << n % integerPartWidth); + } else if (n > srcBits) { + dst[dstParts - 1] &= lowBitMask (srcBits % integerPartWidth); + } + + /* Clear high parts. */ + while (dstParts < dstCount) + dst[dstParts++] = 0; +} + /* DST += RHS + C where C is zero or one. Returns the carry flag. */ integerPart APInt::tcAdd(integerPart *dst, const integerPart *rhs, @@ -2451,31 +2489,33 @@ void APInt::tcShiftLeft(integerPart *dst, unsigned int parts, unsigned int count) { - unsigned int jump, shift; + if (count) { + unsigned int jump, shift; + + /* Jump is the inter-part jump; shift is is intra-part shift. */ + jump = count / integerPartWidth; + shift = count % integerPartWidth; + + while (parts > jump) { + integerPart part; + + parts--; - /* Jump is the inter-part jump; shift is is intra-part shift. */ - jump = count / integerPartWidth; - shift = count % integerPartWidth; - - while (parts > jump) { - integerPart part; - - parts--; - - /* dst[i] comes from the two parts src[i - jump] and, if we have - an intra-part shift, src[i - jump - 1]. */ - part = dst[parts - jump]; - if (shift) { - part <<= shift; + /* dst[i] comes from the two parts src[i - jump] and, if we have + an intra-part shift, src[i - jump - 1]. */ + part = dst[parts - jump]; + if (shift) { + part <<= shift; if (parts >= jump + 1) part |= dst[parts - jump - 1] >> (integerPartWidth - shift); } - dst[parts] = part; - } + dst[parts] = part; + } - while (parts > 0) - dst[--parts] = 0; + while (parts > 0) + dst[--parts] = 0; + } } /* Shift a bignum right COUNT bits in-place. Shifted in bits are @@ -2483,29 +2523,31 @@ void APInt::tcShiftRight(integerPart *dst, unsigned int parts, unsigned int count) { - unsigned int i, jump, shift; - - /* Jump is the inter-part jump; shift is is intra-part shift. */ - jump = count / integerPartWidth; - shift = count % integerPartWidth; + if (count) { + unsigned int i, jump, shift; - /* Perform the shift. This leaves the most significant COUNT bits - of the result at zero. */ - for(i = 0; i < parts; i++) { - integerPart part; - - if (i + jump >= parts) { - part = 0; - } else { - part = dst[i + jump]; - if (shift) { - part >>= shift; - if (i + jump + 1 < parts) - part |= dst[i + jump + 1] << (integerPartWidth - shift); + /* Jump is the inter-part jump; shift is is intra-part shift. */ + jump = count / integerPartWidth; + shift = count % integerPartWidth; + + /* Perform the shift. This leaves the most significant COUNT bits + of the result at zero. */ + for(i = 0; i < parts; i++) { + integerPart part; + + if (i + jump >= parts) { + part = 0; + } else { + part = dst[i + jump]; + if (shift) { + part >>= shift; + if (i + jump + 1 < parts) + part |= dst[i + jump + 1] << (integerPartWidth - shift); + } } - } - dst[i] = part; + dst[i] = part; + } } } From neil at daikokuya.co.uk Mon Oct 8 09:39:42 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Mon, 08 Oct 2007 14:39:42 -0000 Subject: [llvm-commits] [llvm] r42746 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200710081439.l98EdgIg025098@zion.cs.uiuc.edu> Author: neil Date: Mon Oct 8 09:39:42 2007 New Revision: 42746 URL: http://llvm.org/viewvc/llvm-project?rev=42746&view=rev Log: Use APInt::tcExtract. It's cleaner, and works :) Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=42746&r1=42745&r2=42746&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Mon Oct 8 09:39:42 2007 @@ -1556,32 +1556,27 @@ unsigned int srcCount, roundingMode rounding_mode) { - unsigned int dstCount; - lostFraction lost_fraction; + unsigned int omsb, precision, dstCount; integerPart *dst; + lostFraction lost_fraction; category = fcNormal; - exponent = semantics->precision - 1; - + omsb = APInt::tcMSB(src, srcCount) + 1; dst = significandParts(); dstCount = partCount(); + precision = semantics->precision; - /* We need to capture the non-zero most significant parts. */ - while (srcCount > dstCount && src[srcCount - 1] == 0) - srcCount--; - - /* Copy the bit image of as many parts as we can. If we are wider, - zero-out remaining parts. */ - if (dstCount >= srcCount) { - APInt::tcAssign(dst, src, srcCount); - while (srcCount < dstCount) - dst[srcCount++] = 0; - lost_fraction = lfExactlyZero; - } else { - exponent += (srcCount - dstCount) * integerPartWidth; - APInt::tcAssign(dst, src + (srcCount - dstCount), dstCount); + /* We want the most significant PRECISON bits of SRC. There may not + be that many; extract what we can. */ + if (precision <= omsb) { + exponent = omsb - 1; lost_fraction = lostFractionThroughTruncation(src, srcCount, - dstCount * integerPartWidth); + omsb - precision); + APInt::tcExtract(dst, dstCount, src, precision, omsb - precision); + } else { + exponent = precision - 1; + lost_fraction = lfExactlyZero; + APInt::tcExtract(dst, dstCount, src, omsb, 0); } return normalize(rounding_mode, lost_fraction); From djg at cray.com Mon Oct 8 10:08:42 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 08 Oct 2007 15:08:42 -0000 Subject: [llvm-commits] [llvm] r42747 - in /llvm/trunk: include/llvm/Bitcode/Archive.h include/llvm/Bitcode/BitCodes.h include/llvm/Bitcode/BitstreamWriter.h include/llvm/Support/CommandLine.h include/llvm/Target/SubtargetFeature.h lib/VMCore/PassManager.cpp Message-ID: <200710081508.l98F8gGT027078@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 8 10:08:41 2007 New Revision: 42747 URL: http://llvm.org/viewvc/llvm-project?rev=42747&view=rev Log: Add explicit keywords. Modified: llvm/trunk/include/llvm/Bitcode/Archive.h llvm/trunk/include/llvm/Bitcode/BitCodes.h llvm/trunk/include/llvm/Bitcode/BitstreamWriter.h llvm/trunk/include/llvm/Support/CommandLine.h llvm/trunk/include/llvm/Target/SubtargetFeature.h llvm/trunk/lib/VMCore/PassManager.cpp Modified: llvm/trunk/include/llvm/Bitcode/Archive.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Archive.h?rev=42747&r1=42746&r2=42747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Archive.h (original) +++ llvm/trunk/include/llvm/Bitcode/Archive.h Mon Oct 8 10:08:41 2007 @@ -198,7 +198,7 @@ private: /// Used internally by the Archive class to construct an ArchiveMember. /// The contents of the ArchiveMember are filled out by the Archive class. - ArchiveMember(Archive *PAR); + explicit ArchiveMember(Archive *PAR); // So Archive can construct an ArchiveMember friend class llvm::Archive; @@ -461,7 +461,7 @@ protected: /// @brief Construct an Archive for \p filename and optionally map it /// into memory. - Archive(const sys::Path& filename); + explicit Archive(const sys::Path& filename); /// @param data The symbol table data to be parsed /// @param len The length of the symbol table data Modified: llvm/trunk/include/llvm/Bitcode/BitCodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitCodes.h?rev=42747&r1=42746&r2=42747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/BitCodes.h (original) +++ llvm/trunk/include/llvm/Bitcode/BitCodes.h Mon Oct 8 10:08:41 2007 @@ -91,8 +91,8 @@ Char6 = 4 // A 6-bit fixed field which maps to [a-zA-Z0-9._]. }; - BitCodeAbbrevOp(uint64_t V) : Val(V), IsLiteral(true) {} - BitCodeAbbrevOp(Encoding E, uint64_t Data = 0) + explicit BitCodeAbbrevOp(uint64_t V) : Val(V), IsLiteral(true) {} + explicit BitCodeAbbrevOp(Encoding E, uint64_t Data = 0) : Val(Data), IsLiteral(false), Enc(E) {} bool isLiteral() const { return IsLiteral; } Modified: llvm/trunk/include/llvm/Bitcode/BitstreamWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamWriter.h?rev=42747&r1=42746&r2=42747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/BitstreamWriter.h (original) +++ llvm/trunk/include/llvm/Bitcode/BitstreamWriter.h Mon Oct 8 10:08:41 2007 @@ -59,7 +59,7 @@ std::vector BlockInfoRecords; public: - BitstreamWriter(std::vector &O) + explicit BitstreamWriter(std::vector &O) : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {} ~BitstreamWriter() { Modified: llvm/trunk/include/llvm/Support/CommandLine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CommandLine.h?rev=42747&r1=42746&r2=42747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CommandLine.h (original) +++ llvm/trunk/include/llvm/Support/CommandLine.h Mon Oct 8 10:08:41 2007 @@ -838,7 +838,7 @@ // One option... template - opt(const M0t &M0) : Option(Optional | NotHidden) { + explicit opt(const M0t &M0) : Option(Optional | NotHidden) { apply(M0, this); done(); } @@ -998,7 +998,7 @@ // One option... template - list(const M0t &M0) : Option(ZeroOrMore | NotHidden) { + explicit list(const M0t &M0) : Option(ZeroOrMore | NotHidden) { apply(M0, this); done(); } @@ -1184,7 +1184,7 @@ // One option... template - bits(const M0t &M0) : Option(ZeroOrMore | NotHidden) { + explicit bits(const M0t &M0) : Option(ZeroOrMore | NotHidden) { apply(M0, this); done(); } @@ -1277,7 +1277,7 @@ // One option... template - alias(const M0t &M0) : Option(Optional | Hidden), AliasFor(0) { + explicit alias(const M0t &M0) : Option(Optional | Hidden), AliasFor(0) { apply(M0, this); done(); } @@ -1306,7 +1306,7 @@ // aliasfor - Modifier to set the option an alias aliases. struct aliasopt { Option &Opt; - aliasopt(Option &O) : Opt(O) {} + explicit aliasopt(Option &O) : Opt(O) {} void apply(alias &A) const { A.setAliasFor(Opt); } }; Modified: llvm/trunk/include/llvm/Target/SubtargetFeature.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/SubtargetFeature.h?rev=42747&r1=42746&r2=42747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/SubtargetFeature.h (original) +++ llvm/trunk/include/llvm/Target/SubtargetFeature.h Mon Oct 8 10:08:41 2007 @@ -73,7 +73,7 @@ class SubtargetFeatures { std::vector Features; // Subtarget features as a vector public: - SubtargetFeatures(const std::string &Initial = std::string()); + explicit SubtargetFeatures(const std::string &Initial = std::string()); /// Features string accessors. std::string getString() const; Modified: llvm/trunk/lib/VMCore/PassManager.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/PassManager.cpp?rev=42747&r1=42746&r2=42747&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/PassManager.cpp (original) +++ llvm/trunk/lib/VMCore/PassManager.cpp Mon Oct 8 10:08:41 2007 @@ -65,7 +65,7 @@ public: static char ID; - BBPassManager(int Depth) + explicit BBPassManager(int Depth) : PMDataManager(Depth), FunctionPass((intptr_t)&ID) {} /// Execute all of the passes scheduled for execution. Keep track of @@ -121,7 +121,7 @@ public PMTopLevelManager { public: static char ID; - FunctionPassManagerImpl(int Depth) : + explicit FunctionPassManagerImpl(int Depth) : Pass((intptr_t)&ID), PMDataManager(Depth), PMTopLevelManager(TLM_Function) { } @@ -185,7 +185,8 @@ public: static char ID; - MPPassManager(int Depth) : Pass((intptr_t)&ID), PMDataManager(Depth) { } + explicit MPPassManager(int Depth) : + Pass((intptr_t)&ID), PMDataManager(Depth) { } // Delete on the fly managers. virtual ~MPPassManager() { @@ -260,8 +261,9 @@ public: static char ID; - PassManagerImpl(int Depth) : Pass((intptr_t)&ID), PMDataManager(Depth), - PMTopLevelManager(TLM_Pass) { } + explicit PassManagerImpl(int Depth) : + Pass((intptr_t)&ID), PMDataManager(Depth), + PMTopLevelManager(TLM_Pass) { } /// add - Add a pass to the queue of passes to run. This passes ownership of /// the Pass to the PassManager. When the PassManager is destroyed, the pass From djg at cray.com Mon Oct 8 10:10:04 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 08 Oct 2007 15:10:04 -0000 Subject: [llvm-commits] [llvm] r42748 - /llvm/trunk/include/llvm/Support/CommandLine.h Message-ID: <200710081510.l98FA49j027173@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 8 10:10:04 2007 New Revision: 42748 URL: http://llvm.org/viewvc/llvm-project?rev=42748&view=rev Log: Fix grammar in a comment. Modified: llvm/trunk/include/llvm/Support/CommandLine.h Modified: llvm/trunk/include/llvm/Support/CommandLine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CommandLine.h?rev=42748&r1=42747&r2=42748&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CommandLine.h (original) +++ llvm/trunk/include/llvm/Support/CommandLine.h Mon Oct 8 10:10:04 2007 @@ -53,7 +53,7 @@ ///===---------------------------------------------------------------------===// /// SetVersionPrinter - Override the default (LLVM specific) version printer /// used to print out the version when --version is given -/// on the command line. This gives other systems using the +/// on the command line. This allows other systems using the /// CommandLine utilities to print their own version string. void SetVersionPrinter(void (*func)()); From djg at cray.com Mon Oct 8 10:12:17 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 08 Oct 2007 15:12:17 -0000 Subject: [llvm-commits] [llvm] r42749 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200710081512.l98FCH7Q027272@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 8 10:12:17 2007 New Revision: 42749 URL: http://llvm.org/viewvc/llvm-project?rev=42749&view=rev Log: In -debug mode, dump SelectionDAGs both before and after the optimization passes. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=42749&r1=42748&r2=42749&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Oct 8 10:12:17 2007 @@ -4624,10 +4624,13 @@ } void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) { + DOUT << "Lowered selection DAG:\n"; + DEBUG(DAG.dump()); + // Run the DAG combiner in pre-legalize mode. DAG.Combine(false, *AA); - DOUT << "Lowered selection DAG:\n"; + DOUT << "Optimized lowered selection DAG:\n"; DEBUG(DAG.dump()); // Second step, hack on the DAG until it only uses operations and types that @@ -4640,6 +4643,9 @@ // Run the DAG combiner in post-legalize mode. DAG.Combine(true, *AA); + DOUT << "Optimized legalized selection DAG:\n"; + DEBUG(DAG.dump()); + if (ViewISelDAGs) DAG.viewGraph(); // Third, instruction select all of the operations to machine code, adding the From djg at cray.com Mon Oct 8 10:13:30 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 08 Oct 2007 15:13:30 -0000 Subject: [llvm-commits] [llvm] r42750 - /llvm/trunk/lib/Linker/LinkModules.cpp Message-ID: <200710081513.l98FDUxX027367@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 8 10:13:30 2007 New Revision: 42750 URL: http://llvm.org/viewvc/llvm-project?rev=42750&view=rev Log: Use correct parentheses with the '&& "..."' idiom in an assert. Modified: llvm/trunk/lib/Linker/LinkModules.cpp Modified: llvm/trunk/lib/Linker/LinkModules.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=42750&r1=42749&r2=42750&view=diff ============================================================================== --- llvm/trunk/lib/Linker/LinkModules.cpp (original) +++ llvm/trunk/lib/Linker/LinkModules.cpp Mon Oct 8 10:13:30 2007 @@ -469,8 +469,8 @@ if (DGV && DGV->hasInternalLinkage()) DGV = 0; - assert(SGV->hasInitializer() || SGV->hasExternalWeakLinkage() || - SGV->hasExternalLinkage() || SGV->hasDLLImportLinkage() && + assert((SGV->hasInitializer() || SGV->hasExternalWeakLinkage() || + SGV->hasExternalLinkage() || SGV->hasDLLImportLinkage()) && "Global must either be external or have an initializer!"); GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage; From djg at cray.com Mon Oct 8 10:16:25 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 08 Oct 2007 15:16:25 -0000 Subject: [llvm-commits] [llvm] r42751 - /llvm/trunk/lib/Target/TargetData.cpp Message-ID: <200710081516.l98FGPAQ027621@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 8 10:16:25 2007 New Revision: 42751 URL: http://llvm.org/viewvc/llvm-project?rev=42751&view=rev Log: Simplify getIntPtrType, allowing it to work for arbitrary pointer sizes. Modified: llvm/trunk/lib/Target/TargetData.cpp Modified: llvm/trunk/lib/Target/TargetData.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetData.cpp?rev=42751&r1=42750&r2=42751&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetData.cpp (original) +++ llvm/trunk/lib/Target/TargetData.cpp Mon Oct 8 10:16:25 2007 @@ -565,12 +565,7 @@ /// getIntPtrType - Return an unsigned integer type that is the same size or /// greater to the host pointer size. const Type *TargetData::getIntPtrType() const { - switch (getPointerSize()) { - default: assert(0 && "Unknown pointer size!"); - case 2: return Type::Int16Ty; - case 4: return Type::Int32Ty; - case 8: return Type::Int64Ty; - } + return IntegerType::get(getPointerSizeInBits()); } From djg at cray.com Mon Oct 8 10:45:12 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 08 Oct 2007 15:45:12 -0000 Subject: [llvm-commits] [llvm] r42752 - in /llvm/trunk: lib/Support/ tools/bugpoint/ tools/llc/ tools/lli/ tools/llvm-ar/ tools/llvm-as/ tools/llvm-bcanalyzer/ tools/llvm-db/ tools/llvm-dis/ tools/llvm-extract/ tools/llvm-ld/ tools/llvm-link/ tools/llvm-nm/ tools/llvm-prof/ tools/llvm-ranlib/ tools/llvm-upgrade/ tools/llvm2cpp/ tools/llvmc/ tools/opt/ Message-ID: <200710081545.l98FjDut029028@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 8 10:45:12 2007 New Revision: 42752 URL: http://llvm.org/viewvc/llvm-project?rev=42752&view=rev Log: Move the space in overview output for commands out of each of the commands and into the common code. Modified: llvm/trunk/lib/Support/CommandLine.cpp llvm/trunk/tools/bugpoint/bugpoint.cpp llvm/trunk/tools/llc/llc.cpp llvm/trunk/tools/lli/lli.cpp llvm/trunk/tools/llvm-ar/llvm-ar.cpp llvm/trunk/tools/llvm-as/llvm-as.cpp llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp llvm/trunk/tools/llvm-db/llvm-db.cpp llvm/trunk/tools/llvm-dis/llvm-dis.cpp llvm/trunk/tools/llvm-extract/llvm-extract.cpp llvm/trunk/tools/llvm-ld/llvm-ld.cpp llvm/trunk/tools/llvm-link/llvm-link.cpp llvm/trunk/tools/llvm-nm/llvm-nm.cpp llvm/trunk/tools/llvm-prof/llvm-prof.cpp llvm/trunk/tools/llvm-ranlib/llvm-ranlib.cpp llvm/trunk/tools/llvm-upgrade/llvm-upgrade.cpp llvm/trunk/tools/llvm2cpp/llvm2cpp.cpp llvm/trunk/tools/llvmc/llvmc.cpp llvm/trunk/tools/opt/opt.cpp Modified: llvm/trunk/lib/Support/CommandLine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CommandLine.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/lib/Support/CommandLine.cpp (original) +++ llvm/trunk/lib/Support/CommandLine.cpp Mon Oct 8 10:45:12 2007 @@ -951,7 +951,7 @@ } if (ProgramOverview) - cout << "OVERVIEW:" << ProgramOverview << "\n"; + cout << "OVERVIEW: " << ProgramOverview << "\n"; cout << "USAGE: " << ProgramName << " [options]"; Modified: llvm/trunk/tools/bugpoint/bugpoint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/bugpoint.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/bugpoint.cpp (original) +++ llvm/trunk/tools/bugpoint/bugpoint.cpp Mon Oct 8 10:45:12 2007 @@ -66,7 +66,7 @@ int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, - " LLVM automatic testcase reducer. See\nhttp://" + "LLVM automatic testcase reducer. See\nhttp://" "llvm.org/docs/CommandGuide/bugpoint.html" " for more information.\n"); sys::PrintStackTraceOnErrorSignal(); Modified: llvm/trunk/tools/llc/llc.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llc/llc.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llc/llc.cpp (original) +++ llvm/trunk/tools/llc/llc.cpp Mon Oct 8 10:45:12 2007 @@ -172,7 +172,7 @@ // int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n"); + cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); sys::PrintStackTraceOnErrorSignal(); // Load the module to be compiled... Modified: llvm/trunk/tools/lli/lli.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/lli/lli.cpp (original) +++ llvm/trunk/tools/lli/lli.cpp Mon Oct 8 10:45:12 2007 @@ -67,7 +67,7 @@ int main(int argc, char **argv, char * const *envp) { atexit(do_shutdown); // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, - " llvm interpreter & dynamic compiler\n"); + "llvm interpreter & dynamic compiler\n"); sys::PrintStackTraceOnErrorSignal(); // If the user doesn't want core files, disable them. Modified: llvm/trunk/tools/llvm-ar/llvm-ar.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-ar/llvm-ar.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvm-ar/llvm-ar.cpp (original) +++ llvm/trunk/tools/llvm-ar/llvm-ar.cpp Mon Oct 8 10:45:12 2007 @@ -690,7 +690,7 @@ // Have the command line options parsed and handle things // like --help and --version. cl::ParseCommandLineOptions(argc, argv, - " LLVM Archiver (llvm-ar)\n\n" + "LLVM Archiver (llvm-ar)\n\n" " This program archives bitcode files into single libraries\n" ); Modified: llvm/trunk/tools/llvm-as/llvm-as.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-as/llvm-as.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvm-as/llvm-as.cpp (original) +++ llvm/trunk/tools/llvm-as/llvm-as.cpp Mon Oct 8 10:45:12 2007 @@ -48,7 +48,7 @@ int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, " llvm .ll -> .bc assembler\n"); + cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .bc assembler\n"); sys::PrintStackTraceOnErrorSignal(); int exitCode = 0; Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original) +++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Mon Oct 8 10:45:12 2007 @@ -496,7 +496,7 @@ int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, " llvm-bcanalyzer file analyzer\n"); + cl::ParseCommandLineOptions(argc, argv, "llvm-bcanalyzer file analyzer\n"); sys::PrintStackTraceOnErrorSignal(); Modified: llvm/trunk/tools/llvm-db/llvm-db.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-db/llvm-db.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvm-db/llvm-db.cpp (original) +++ llvm/trunk/tools/llvm-db/llvm-db.cpp Mon Oct 8 10:45:12 2007 @@ -53,7 +53,7 @@ std::cout << "NOTE: llvm-db is known useless right now.\n"; try { cl::ParseCommandLineOptions(argc, argv, - " llvm source-level debugger\n"); + "llvm source-level debugger\n"); sys::PrintStackTraceOnErrorSignal(); if (!Quiet) Modified: llvm/trunk/tools/llvm-dis/llvm-dis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dis/llvm-dis.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvm-dis/llvm-dis.cpp (original) +++ llvm/trunk/tools/llvm-dis/llvm-dis.cpp Mon Oct 8 10:45:12 2007 @@ -46,7 +46,7 @@ int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. try { - cl::ParseCommandLineOptions(argc, argv, " llvm .bc -> .ll disassembler\n"); + cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); sys::PrintStackTraceOnErrorSignal(); std::ostream *Out = &std::cout; // Default to printing to stdout. Modified: llvm/trunk/tools/llvm-extract/llvm-extract.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-extract/llvm-extract.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvm-extract/llvm-extract.cpp (original) +++ llvm/trunk/tools/llvm-extract/llvm-extract.cpp Mon Oct 8 10:45:12 2007 @@ -52,7 +52,7 @@ int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n"); + cl::ParseCommandLineOptions(argc, argv, "llvm extractor\n"); sys::PrintStackTraceOnErrorSignal(); std::auto_ptr M; Modified: llvm/trunk/tools/llvm-ld/llvm-ld.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-ld/llvm-ld.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvm-ld/llvm-ld.cpp (original) +++ llvm/trunk/tools/llvm-ld/llvm-ld.cpp Mon Oct 8 10:45:12 2007 @@ -469,7 +469,7 @@ progname = sys::Path(argv[0]).getBasename(); // Parse the command line options - cl::ParseCommandLineOptions(argc, argv, " llvm linker\n"); + cl::ParseCommandLineOptions(argc, argv, "llvm linker\n"); sys::PrintStackTraceOnErrorSignal(); // Construct a Linker (now that Verbose is set) Modified: llvm/trunk/tools/llvm-link/llvm-link.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-link/llvm-link.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvm-link/llvm-link.cpp (original) +++ llvm/trunk/tools/llvm-link/llvm-link.cpp Mon Oct 8 10:45:12 2007 @@ -79,7 +79,7 @@ int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, " llvm linker\n"); + cl::ParseCommandLineOptions(argc, argv, "llvm linker\n"); sys::PrintStackTraceOnErrorSignal(); assert(InputFilenames.size() > 0 && "OneOrMore is not working"); Modified: llvm/trunk/tools/llvm-nm/llvm-nm.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-nm/llvm-nm.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvm-nm/llvm-nm.cpp (original) +++ llvm/trunk/tools/llvm-nm/llvm-nm.cpp Mon Oct 8 10:45:12 2007 @@ -165,7 +165,7 @@ int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, " llvm symbol table dumper\n"); + cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n"); sys::PrintStackTraceOnErrorSignal(); ToolName = argv[0]; Modified: llvm/trunk/tools/llvm-prof/llvm-prof.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-prof/llvm-prof.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvm-prof/llvm-prof.cpp (original) +++ llvm/trunk/tools/llvm-prof/llvm-prof.cpp Mon Oct 8 10:45:12 2007 @@ -112,7 +112,7 @@ int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. try { - cl::ParseCommandLineOptions(argc, argv, " llvm profile dump decoder\n"); + cl::ParseCommandLineOptions(argc, argv, "llvm profile dump decoder\n"); sys::PrintStackTraceOnErrorSignal(); // Read in the bitcode file... Modified: llvm/trunk/tools/llvm-ranlib/llvm-ranlib.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-ranlib/llvm-ranlib.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvm-ranlib/llvm-ranlib.cpp (original) +++ llvm/trunk/tools/llvm-ranlib/llvm-ranlib.cpp Mon Oct 8 10:45:12 2007 @@ -47,7 +47,7 @@ // Have the command line options parsed and handle things // like --help and --version. cl::ParseCommandLineOptions(argc, argv, - " LLVM Archive Index Generator (llvm-ranlib)\n\n" + "LLVM Archive Index Generator (llvm-ranlib)\n\n" " This program adds or updates an index of bitcode symbols\n" " to an LLVM archive file." ); Modified: llvm/trunk/tools/llvm-upgrade/llvm-upgrade.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-upgrade/llvm-upgrade.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvm-upgrade/llvm-upgrade.cpp (original) +++ llvm/trunk/tools/llvm-upgrade/llvm-upgrade.cpp Mon Oct 8 10:45:12 2007 @@ -51,7 +51,7 @@ int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, " llvm .ll -> .bc assembler\n"); + cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .bc assembler\n"); sys::PrintStackTraceOnErrorSignal(); int exitCode = 0; Modified: llvm/trunk/tools/llvm2cpp/llvm2cpp.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm2cpp/llvm2cpp.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvm2cpp/llvm2cpp.cpp (original) +++ llvm/trunk/tools/llvm2cpp/llvm2cpp.cpp Mon Oct 8 10:45:12 2007 @@ -43,7 +43,7 @@ int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, " llvm .ll -> .cpp assembler\n"); + cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .cpp assembler\n"); sys::PrintStackTraceOnErrorSignal(); int exitCode = 0; Modified: llvm/trunk/tools/llvmc/llvmc.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/llvmc.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/llvmc.cpp (original) +++ llvm/trunk/tools/llvmc/llvmc.cpp Mon Oct 8 10:45:12 2007 @@ -257,7 +257,7 @@ // Parse the command line options cl::ParseCommandLineOptions(argc, argv, - " LLVM Compiler Driver (llvmc)\n\n" + "LLVM Compiler Driver (llvmc)\n\n" " This program provides easy invocation of the LLVM tool set\n" " and other compiler tools.\n" ); Modified: llvm/trunk/tools/opt/opt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=42752&r1=42751&r2=42752&view=diff ============================================================================== --- llvm/trunk/tools/opt/opt.cpp (original) +++ llvm/trunk/tools/opt/opt.cpp Mon Oct 8 10:45:12 2007 @@ -308,7 +308,7 @@ llvm_shutdown_obj X; // Call llvm_shutdown() on exit. try { cl::ParseCommandLineOptions(argc, argv, - " llvm .bc -> .bc modular optimizer and analysis printer \n"); + "llvm .bc -> .bc modular optimizer and analysis printer\n"); sys::PrintStackTraceOnErrorSignal(); // Allocate a full target machine description only if necessary. From djg at cray.com Mon Oct 8 10:49:58 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 08 Oct 2007 15:49:58 -0000 Subject: [llvm-commits] [llvm] r42753 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200710081549.l98Fnw66029193@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 8 10:49:58 2007 New Revision: 42753 URL: http://llvm.org/viewvc/llvm-project?rev=42753&view=rev Log: Add convenience overloads of SelectionDAG::getNode that take a SDVTList and individual SDOperand operands. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=42753&r1=42752&r2=42753&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Mon Oct 8 10:49:58 2007 @@ -287,6 +287,17 @@ const SDOperand *Ops, unsigned NumOps); SDOperand getNode(unsigned Opcode, const MVT::ValueType *VTs, unsigned NumVTs, const SDOperand *Ops, unsigned NumOps); + SDOperand getNode(unsigned Opcode, SDVTList VTs); + SDOperand getNode(unsigned Opcode, SDVTList VTs, SDOperand N); + SDOperand getNode(unsigned Opcode, SDVTList VTs, + SDOperand N1, SDOperand N2); + SDOperand getNode(unsigned Opcode, SDVTList VTs, + SDOperand N1, SDOperand N2, SDOperand N3); + SDOperand getNode(unsigned Opcode, SDVTList VTs, + SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4); + SDOperand getNode(unsigned Opcode, SDVTList VTs, + SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4, + SDOperand N5); SDOperand getNode(unsigned Opcode, SDVTList VTs, const SDOperand *Ops, unsigned NumOps); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=42753&r1=42752&r2=42753&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Oct 8 10:49:58 2007 @@ -2595,6 +2595,42 @@ return SDOperand(N, 0); } +SDOperand SelectionDAG::getNode(unsigned Opcode, SDVTList VTList) { + return getNode(Opcode, VTList, 0, 0); +} + +SDOperand SelectionDAG::getNode(unsigned Opcode, SDVTList VTList, + SDOperand N1) { + SDOperand Ops[] = { N1 }; + return getNode(Opcode, VTList, Ops, 1); +} + +SDOperand SelectionDAG::getNode(unsigned Opcode, SDVTList VTList, + SDOperand N1, SDOperand N2) { + SDOperand Ops[] = { N1, N2 }; + return getNode(Opcode, VTList, Ops, 2); +} + +SDOperand SelectionDAG::getNode(unsigned Opcode, SDVTList VTList, + SDOperand N1, SDOperand N2, SDOperand N3) { + SDOperand Ops[] = { N1, N2, N3 }; + return getNode(Opcode, VTList, Ops, 3); +} + +SDOperand SelectionDAG::getNode(unsigned Opcode, SDVTList VTList, + SDOperand N1, SDOperand N2, SDOperand N3, + SDOperand N4) { + SDOperand Ops[] = { N1, N2, N3, N4 }; + return getNode(Opcode, VTList, Ops, 4); +} + +SDOperand SelectionDAG::getNode(unsigned Opcode, SDVTList VTList, + SDOperand N1, SDOperand N2, SDOperand N3, + SDOperand N4, SDOperand N5) { + SDOperand Ops[] = { N1, N2, N3, N4, N5 }; + return getNode(Opcode, VTList, Ops, 5); +} + SDVTList SelectionDAG::getVTList(MVT::ValueType VT) { if (!MVT::isExtendedVT(VT)) return makeVTList(SDNode::getValueTypeList(VT), 1); From djg at cray.com Mon Oct 8 12:28:28 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 08 Oct 2007 17:28:28 -0000 Subject: [llvm-commits] [llvm] r42755 - /llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200710081728.l98HSSDH032260@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 8 12:28:24 2007 New Revision: 42755 URL: http://llvm.org/viewvc/llvm-project?rev=42755&view=rev Log: When we start enabling SMUL_LOHI/UMUL_LOHI or SDIVREM/UDIVREM in target-indepenent lowering, don't use them on PowerPC. Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=42755&r1=42754&r2=42755&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Mon Oct 8 12:28:24 2007 @@ -87,6 +87,16 @@ setOperationAction(ISD::UREM, MVT::i32, Expand); setOperationAction(ISD::SREM, MVT::i64, Expand); setOperationAction(ISD::UREM, MVT::i64, Expand); + + // Don't use SMUL_LOHI/UMUL_LOHI or SDIVREM/UDIVREM to lower SREM/UREM. + setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); + setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); + setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand); + setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand); + setOperationAction(ISD::UDIVREM, MVT::i32, Expand); + setOperationAction(ISD::SDIVREM, MVT::i32, Expand); + setOperationAction(ISD::UDIVREM, MVT::i64, Expand); + setOperationAction(ISD::SDIVREM, MVT::i64, Expand); // We don't support sin/cos/sqrt/fmod setOperationAction(ISD::FSIN , MVT::f64, Expand); @@ -265,6 +275,10 @@ setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Expand); setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Expand); setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::UMUL_LOHI, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::SMUL_LOHI, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::UDIVREM, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::SDIVREM, (MVT::ValueType)VT, Expand); setOperationAction(ISD::SCALAR_TO_VECTOR, (MVT::ValueType)VT, Expand); } From evan.cheng at apple.com Mon Oct 8 12:48:37 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 8 Oct 2007 10:48:37 -0700 Subject: [llvm-commits] [llvm] r42736 - in /llvm/trunk: Xcode/LLVM.xcodeproj/project.pbxproj bindings/ocaml/llvm/llvm.ml bindings/ocaml/llvm/llvm.mli bindings/ocaml/llvm/llvm_ocaml.c include/llvm-c/Core.h lib/VMCore/Core.cpp test/Bindings/Ocaml/vmcore.ml In-Reply-To: <200710071731.l97HVhjH001572@zion.cs.uiuc.edu> References: <200710071731.l97HVhjH001572@zion.cs.uiuc.edu> Message-ID: Hi Gordon, On Oct 7, 2007, at 10:31 AM, Gordon Henriksen wrote: > > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/VMCore/Core.cpp (original) > +++ llvm/trunk/lib/VMCore/Core.cpp Sun Oct 7 12:31:42 2007 > @@ -557,6 +557,17 @@ > unwrap(GlobalVar)->setThreadLocal(IsThreadLocal != > 0); > } > > +int LLVMIsGlobalConstant(LLVMValueRef GlobalVar) { > + bool res = unwrap(GlobalVar)->isConstant(); > + fprintf(stderr, "LLVMIsConstantGlobal(0x%08x) = %s\n", > + (int) GlobalVar, res? "YES" : "NO"); This is breaking the build on 64-bit machine: Core.cpp:567: error: cast from 'LLVMOpaqueValue*' to 'int' loses precision Also, please don't leave debugging printf's in. Thanks, Evan > > + return unwrap(GlobalVar)->isConstant(); > +} > + > +void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, int IsConstant) { > + unwrap(GlobalVar)->setConstant(IsConstant != 0); > +} > + > /*--.. Operations on > functions .............................................--*/ From evan.cheng at apple.com Mon Oct 8 12:49:44 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 08 Oct 2007 17:49:44 -0000 Subject: [llvm-commits] [llvm] r42757 - /llvm/trunk/lib/VMCore/Core.cpp Message-ID: <200710081749.l98HniRY000368@zion.cs.uiuc.edu> Author: evancheng Date: Mon Oct 8 12:49:43 2007 New Revision: 42757 URL: http://llvm.org/viewvc/llvm-project?rev=42757&view=rev Log: Remove debugging printf to get build going on x86-64. Modified: llvm/trunk/lib/VMCore/Core.cpp Modified: llvm/trunk/lib/VMCore/Core.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=42757&r1=42756&r2=42757&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Core.cpp (original) +++ llvm/trunk/lib/VMCore/Core.cpp Mon Oct 8 12:49:43 2007 @@ -563,8 +563,6 @@ int LLVMIsGlobalConstant(LLVMValueRef GlobalVar) { bool res = unwrap(GlobalVar)->isConstant(); - fprintf(stderr, "LLVMIsConstantGlobal(0x%08x) = %s\n", - (int) GlobalVar, res? "YES" : "NO"); return unwrap(GlobalVar)->isConstant(); } From evan.cheng at apple.com Mon Oct 8 12:54:24 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 08 Oct 2007 17:54:24 -0000 Subject: [llvm-commits] [llvm] r42758 - /llvm/trunk/docs/CodeGenerator.html Message-ID: <200710081754.l98HsOHC000518@zion.cs.uiuc.edu> Author: evancheng Date: Mon Oct 8 12:54:24 2007 New Revision: 42758 URL: http://llvm.org/viewvc/llvm-project?rev=42758&view=rev Log: LLVM does not use the old style simple isel any more. Modified: llvm/trunk/docs/CodeGenerator.html Modified: llvm/trunk/docs/CodeGenerator.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodeGenerator.html?rev=42758&r1=42757&r2=42758&view=diff ============================================================================== --- llvm/trunk/docs/CodeGenerator.html (original) +++ llvm/trunk/docs/CodeGenerator.html Mon Oct 8 12:54:24 2007 @@ -748,11 +748,8 @@

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 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. +well-known ways to do this in the literature. LLVM uses a SelectionDAG based +instruction selector.

Portions of the DAG instruction selector are generated from the target From djg at cray.com Mon Oct 8 12:57:15 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 08 Oct 2007 17:57:15 -0000 Subject: [llvm-commits] [llvm] r42759 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200710081757.l98HvFhw000598@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 8 12:57:15 2007 New Revision: 42759 URL: http://llvm.org/viewvc/llvm-project?rev=42759&view=rev Log: DAGCombiner support for UDIVREM/SDIVREM and UMUL_LOHI/SMUL_LOHI. Check if one of the two results unneeded so see if a simpler operator could bs used. Also check to see if each of the two computations could be simplified if they were split into separate operators. Factor out the code that calls visit() so that it can be used for this purpose. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=42759&r1=42758&r2=42759&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Oct 8 12:57:15 2007 @@ -101,6 +101,10 @@ WorkList.end()); } + /// visit - call the node-specific routine that knows how to fold each + /// particular type of node. + SDOperand visit(SDNode *N); + public: /// AddToWorkList - Add to the work list making sure it's instance is at the /// the back (next to be processed.) @@ -201,9 +205,10 @@ bool CombineToPostIndexedLoadStore(SDNode *N); - /// visit - call the node-specific routine that knows how to fold each - /// particular type of node. - SDOperand visit(SDNode *N); + /// combine - call the node-specific routine that knows how to fold each + /// particular type of node. If that doesn't do anything, try the + /// target-specific DAG combines. + SDOperand combine(SDNode *N); // Visitation implementation - Implement dag node combining for different // node types. The semantics are as follows: @@ -224,6 +229,10 @@ SDOperand visitUREM(SDNode *N); SDOperand visitMULHU(SDNode *N); SDOperand visitMULHS(SDNode *N); + SDOperand visitSMUL_LOHI(SDNode *N); + SDOperand visitUMUL_LOHI(SDNode *N); + SDOperand visitSDIVREM(SDNode *N); + SDOperand visitUDIVREM(SDNode *N); SDOperand visitAND(SDNode *N); SDOperand visitOR(SDNode *N); SDOperand visitXOR(SDNode *N); @@ -279,6 +288,7 @@ bool NotExtCompare = false); SDOperand SimplifySetCC(MVT::ValueType VT, SDOperand N0, SDOperand N1, ISD::CondCode Cond, bool foldBooleans = true); + bool SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp, unsigned HiOp); SDOperand ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *, MVT::ValueType); SDOperand BuildSDIV(SDNode *N); SDOperand BuildUDIV(SDNode *N); @@ -555,10 +565,6 @@ // done. Set it to null to avoid confusion. DAG.setRoot(SDOperand()); - /// DagCombineInfo - Expose the DAG combiner to the target combiner impls. - TargetLowering::DAGCombinerInfo - DagCombineInfo(DAG, !RunningAfterLegalize, false, this); - // while the worklist isn't empty, inspect the node on the end of it and // try and combine it. while (!WorkList.empty()) { @@ -576,16 +582,7 @@ continue; } - SDOperand RV = visit(N); - - // If nothing happened, try a target-specific DAG combine. - if (RV.Val == 0) { - assert(N->getOpcode() != ISD::DELETED_NODE && - "Node was deleted but visit returned NULL!"); - if (N->getOpcode() >= ISD::BUILTIN_OP_END || - TLI.hasTargetDAGCombine((ISD::NodeType)N->getOpcode())) - RV = TLI.PerformDAGCombine(N, DagCombineInfo); - } + SDOperand RV = combine(N); if (RV.Val) { ++NodesCombined; @@ -645,6 +642,10 @@ case ISD::UREM: return visitUREM(N); case ISD::MULHU: return visitMULHU(N); case ISD::MULHS: return visitMULHS(N); + case ISD::SMUL_LOHI: return visitSMUL_LOHI(N); + case ISD::UMUL_LOHI: return visitUMUL_LOHI(N); + case ISD::SDIVREM: return visitSDIVREM(N); + case ISD::UDIVREM: return visitUDIVREM(N); case ISD::AND: return visitAND(N); case ISD::OR: return visitOR(N); case ISD::XOR: return visitXOR(N); @@ -691,6 +692,29 @@ return SDOperand(); } +SDOperand DAGCombiner::combine(SDNode *N) { + + SDOperand RV = visit(N); + + // If nothing happened, try a target-specific DAG combine. + if (RV.Val == 0) { + assert(N->getOpcode() != ISD::DELETED_NODE && + "Node was deleted but visit returned NULL!"); + + if (N->getOpcode() >= ISD::BUILTIN_OP_END || + TLI.hasTargetDAGCombine((ISD::NodeType)N->getOpcode())) { + + // Expose the DAG combiner to the target combiner impls. + TargetLowering::DAGCombinerInfo + DagCombineInfo(DAG, !AfterLegalize, false, this); + + RV = TLI.PerformDAGCombine(N, DagCombineInfo); + } + } + + return RV; +} + /// getInputChainForNode - Given a node, return its input chain if it has one, /// otherwise return a null sd operand. static SDOperand getInputChainForNode(SDNode *N) { @@ -1382,6 +1406,102 @@ return SDOperand(); } +/// SimplifyNodeWithTwoResults - Perform optimizations common to nodes that +/// compute two values. LoOp and HiOp give the opcodes for the two computations +/// that are being performed. Return true if a simplification was made. +/// +bool DAGCombiner::SimplifyNodeWithTwoResults(SDNode *N, + unsigned LoOp, unsigned HiOp) { + std::vector NowDead; + + // If the high half is not needed, just compute the low half. + if (!N->hasAnyUseOfValue(1) && + (!AfterLegalize || + TLI.isOperationLegal(LoOp, N->getValueType(0)))) { + DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), + DAG.getNode(LoOp, N->getValueType(0), + N->op_begin(), + N->getNumOperands()), + NowDead); + return true; + } + + // If the low half is not needed, just compute the high half. + if (!N->hasAnyUseOfValue(0) && + (!AfterLegalize || + TLI.isOperationLegal(HiOp, N->getValueType(1)))) { + DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), + DAG.getNode(HiOp, N->getValueType(1), + N->op_begin(), + N->getNumOperands()), + NowDead); + return true; + } + + // If the two computed results can be siplified separately, separate them. + SDOperand Lo = DAG.getNode(LoOp, N->getValueType(0), + N->op_begin(), N->getNumOperands()); + SDOperand Hi = DAG.getNode(HiOp, N->getValueType(1), + N->op_begin(), N->getNumOperands()); + unsigned LoExists = !Lo.use_empty(); + unsigned HiExists = !Hi.use_empty(); + SDOperand LoOpt = Lo; + SDOperand HiOpt = Hi; + if (!LoExists || !HiExists) { + SDOperand Pair = DAG.getNode(ISD::BUILD_PAIR, MVT::Other, Lo, Hi); + assert(Pair.use_empty() && "Pair with type MVT::Other already exists!"); + LoOpt = combine(Lo.Val); + HiOpt = combine(Hi.Val); + if (!LoOpt.Val) + LoOpt = Pair.getOperand(0); + if (!HiOpt.Val) + HiOpt = Pair.getOperand(1); + DAG.DeleteNode(Pair.Val); + } + if ((LoExists || LoOpt != Lo) && + (HiExists || HiOpt != Hi) && + TLI.isOperationLegal(LoOpt.getOpcode(), LoOpt.getValueType()) && + TLI.isOperationLegal(HiOpt.getOpcode(), HiOpt.getValueType())) { + DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), LoOpt, NowDead); + DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), HiOpt, NowDead); + return true; + } + + return false; +} + +SDOperand DAGCombiner::visitSMUL_LOHI(SDNode *N) { + + if (SimplifyNodeWithTwoResults(N, ISD::MUL, ISD::MULHS)) + return SDOperand(); + + return SDOperand(); +} + +SDOperand DAGCombiner::visitUMUL_LOHI(SDNode *N) { + + if (SimplifyNodeWithTwoResults(N, ISD::MUL, ISD::MULHU)) + return SDOperand(); + + return SDOperand(); +} + +SDOperand DAGCombiner::visitSDIVREM(SDNode *N) { + + if (SimplifyNodeWithTwoResults(N, ISD::SDIV, ISD::SREM)) + return SDOperand(); + + return SDOperand(); +} + +SDOperand DAGCombiner::visitUDIVREM(SDNode *N) { + + if (SimplifyNodeWithTwoResults(N, ISD::UDIV, ISD::UREM)) + return SDOperand(); + + return SDOperand(); +} + /// SimplifyBinOpWithSameOpcodeHands - If this is a binary operator with /// two operands of the same opcode, try to simplify it. SDOperand DAGCombiner::SimplifyBinOpWithSameOpcodeHands(SDNode *N) { From gordonhenriksen at mac.com Mon Oct 8 13:14:40 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Mon, 08 Oct 2007 18:14:40 -0000 Subject: [llvm-commits] [llvm] r42760 - in /llvm/trunk: bindings/ocaml/llvm/llvm.ml bindings/ocaml/llvm/llvm.mli bindings/ocaml/llvm/llvm_ocaml.c include/llvm-c/Core.h lib/VMCore/Core.cpp test/Bindings/Ocaml/vmcore.ml Message-ID: <200710081814.l98IEeY4001099@zion.cs.uiuc.edu> Author: gordon Date: Mon Oct 8 13:14:39 2007 New Revision: 42760 URL: http://llvm.org/viewvc/llvm-project?rev=42760&view=rev Log: C and Objective Caml bindings for PHINode::addIncoming etc. Modified: llvm/trunk/bindings/ocaml/llvm/llvm.ml llvm/trunk/bindings/ocaml/llvm/llvm.mli llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c llvm/trunk/include/llvm-c/Core.h llvm/trunk/lib/VMCore/Core.cpp llvm/trunk/test/Bindings/Ocaml/vmcore.ml Modified: llvm/trunk/bindings/ocaml/llvm/llvm.ml URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm.ml?rev=42760&r1=42759&r2=42760&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm.ml (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm.ml Mon Oct 8 13:14:39 2007 @@ -314,6 +314,11 @@ external value_is_block : llvalue -> bool = "llvm_value_is_block" external block_of_value : llvalue -> llbasicblock = "LLVMValueAsBasicBlock" +(*--... Operations on phi nodes ............................................--*) +external add_incoming : (llvalue * llbasicblock) -> llvalue -> unit + = "llvm_add_incoming" +external incoming : llvalue -> (llvalue * llbasicblock) list = "llvm_incoming" + (*===-- Instruction builders ----------------------------------------------===*) external builder_before : llvalue -> llbuilder = "llvm_builder_before" @@ -422,7 +427,8 @@ llbuilder -> llvalue = "llvm_build_fcmp" (*--... Miscellaneous instructions .........................................--*) -external build_phi : lltype -> string -> llbuilder -> llvalue = "llvm_build_phi" +external build_phi : (llvalue * llbasicblock) list -> string -> llbuilder -> + llvalue = "llvm_build_phi" external build_call : llvalue -> llvalue array -> string -> llbuilder -> llvalue = "llvm_build_call" external build_select : llvalue -> llvalue -> llvalue -> string -> llbuilder -> Modified: llvm/trunk/bindings/ocaml/llvm/llvm.mli URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm.mli?rev=42760&r1=42759&r2=42760&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm.mli (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm.mli Mon Oct 8 13:14:39 2007 @@ -295,6 +295,11 @@ external value_is_block : llvalue -> bool = "llvm_value_is_block" external block_of_value : llvalue -> llbasicblock = "LLVMValueAsBasicBlock" +(*--... Operations on phi nodes ............................................--*) +external add_incoming : (llvalue * llbasicblock) -> llvalue -> unit + = "llvm_add_incoming" +external incoming : llvalue -> (llvalue * llbasicblock) list = "llvm_incoming" + (*===-- Instruction builders ----------------------------------------------===*) external builder_before : llvalue -> llbuilder = "llvm_builder_before" @@ -403,7 +408,8 @@ llbuilder -> llvalue = "llvm_build_fcmp" (*--... Miscellaneous instructions .........................................--*) -external build_phi : lltype -> string -> llbuilder -> llvalue = "llvm_build_phi" +external build_phi : (llvalue * llbasicblock) list -> string -> llbuilder -> + llvalue = "llvm_build_phi" external build_call : llvalue -> llvalue array -> string -> llbuilder -> llvalue = "llvm_build_call" external build_select : llvalue -> llvalue -> llvalue -> string -> llbuilder -> Modified: llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c?rev=42760&r1=42759&r2=42760&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c Mon Oct 8 13:14:39 2007 @@ -21,6 +21,7 @@ #include "caml/mlvalues.h" #include "caml/memory.h" #include "llvm/Config/config.h" +#include /*===-- Modules -----------------------------------------------------------===*/ @@ -572,6 +573,39 @@ return Val_bool(LLVMValueIsBasicBlock(Val)); } +/*--... Operations on phi nodes ............................................--*/ + +/* (llvalue * llbasicblock) -> llvalue -> unit */ +CAMLprim value llvm_add_incoming(value Incoming, LLVMValueRef PhiNode) { + LLVMAddIncoming(PhiNode, + (LLVMValueRef*) &Field(Incoming, 0), + (LLVMBasicBlockRef*) &Field(Incoming, 1), + 1); + return Val_unit; +} + +/* llvalue -> (llvalue * llbasicblock) list */ +CAMLprim value llvm_incoming(LLVMValueRef PhiNode) { + unsigned I; + CAMLparam0(); + CAMLlocal3(Hd, Tl, Tmp); + + /* Build a tuple list of them. */ + Tl = Val_int(0); + for (I = LLVMCountIncoming(PhiNode); I != 0; ) { + Hd = alloc(2, 0); + Store_field(Hd, 0, (value) LLVMGetIncomingValue(PhiNode, --I)); + Store_field(Hd, 1, (value) LLVMGetIncomingBlock(PhiNode, I)); + + Tmp = alloc(2, 0); + Store_field(Tmp, 0, Hd); + Store_field(Tmp, 1, Tl); + Tl = Tmp; + } + + CAMLreturn(Tl); +} + /*===-- Instruction builders ----------------------------------------------===*/ @@ -933,10 +967,25 @@ /*--... Miscellaneous instructions .........................................--*/ -/* lltype -> string -> llbuilder -> llvalue */ -CAMLprim LLVMValueRef llvm_build_phi(LLVMTypeRef Ty, - value Name, value B) { - return LLVMBuildPhi(Builder_val(B), Ty, String_val(Name)); +/* (llvalue * llbasicblock) list -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_phi(value Incoming, value Name, value B) { + value Hd, Tl; + LLVMValueRef FirstValue, PhiNode; + + assert(Incoming != Val_int(0) && "Empty list passed to Llvm.build_phi!"); + + Hd = Field(Incoming, 0); + FirstValue = (LLVMValueRef) Field(Hd, 0); + PhiNode = LLVMBuildPhi(Builder_val(B), LLVMTypeOf(FirstValue), + String_val(Name)); + + for (Tl = Incoming; Tl != Val_int(0); Tl = Field(Tl, 1)) { + value Hd = Field(Tl, 0); + LLVMAddIncoming(PhiNode, (LLVMValueRef*) &Field(Hd, 0), + (LLVMBasicBlockRef*) &Field(Hd, 1), 1); + } + + return PhiNode; } /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */ Modified: llvm/trunk/include/llvm-c/Core.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=42760&r1=42759&r2=42760&view=diff ============================================================================== --- llvm/trunk/include/llvm-c/Core.h (original) +++ llvm/trunk/include/llvm-c/Core.h Mon Oct 8 13:14:39 2007 @@ -352,6 +352,12 @@ const char *Name); void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB); +/* Operations on phi nodes */ +void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues, + LLVMBasicBlockRef *IncomingBlocks, unsigned Count); +unsigned LLVMCountIncoming(LLVMValueRef PhiNode); +LLVMValueRef LLVMGetIncomingValue(LLVMValueRef PhiNode, unsigned Index); +LLVMBasicBlockRef LLVMGetIncomingBlock(LLVMValueRef PhiNode, unsigned Index); /*===-- Instruction builders ----------------------------------------------===*/ Modified: llvm/trunk/lib/VMCore/Core.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=42760&r1=42759&r2=42760&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Core.cpp (original) +++ llvm/trunk/lib/VMCore/Core.cpp Mon Oct 8 13:14:39 2007 @@ -562,7 +562,6 @@ } int LLVMIsGlobalConstant(LLVMValueRef GlobalVar) { - bool res = unwrap(GlobalVar)->isConstant(); return unwrap(GlobalVar)->isConstant(); } @@ -684,6 +683,27 @@ assert(0 && "LLVMSetInstructionCallConv applies only to call and invoke!"); } +/*--.. Operations on phi nodes .............................................--*/ + +void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues, + LLVMBasicBlockRef *IncomingBlocks, unsigned Count) { + PHINode *PhiVal = unwrap(PhiNode); + for (unsigned I = 0; I != Count; ++I) + PhiVal->addIncoming(unwrap(IncomingValues[I]), unwrap(IncomingBlocks[I])); +} + +unsigned LLVMCountIncoming(LLVMValueRef PhiNode) { + return unwrap(PhiNode)->getNumIncomingValues(); +} + +LLVMValueRef LLVMGetIncomingValue(LLVMValueRef PhiNode, unsigned Index) { + return wrap(unwrap(PhiNode)->getIncomingValue(Index)); +} + +LLVMBasicBlockRef LLVMGetIncomingBlock(LLVMValueRef PhiNode, unsigned Index) { + return wrap(unwrap(PhiNode)->getIncomingBlock(Index)); +} + /*===-- Instruction builders ----------------------------------------------===*/ Modified: llvm/trunk/test/Bindings/Ocaml/vmcore.ml URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/Ocaml/vmcore.ml?rev=42760&r1=42759&r2=42760&view=diff ============================================================================== --- llvm/trunk/test/Bindings/Ocaml/vmcore.ml (original) +++ llvm/trunk/test/Bindings/Ocaml/vmcore.ml Mon Oct 8 13:14:39 2007 @@ -1,4 +1,4 @@ -(* RUN: %ocamlc llvm.cma llvm_bitwriter.cma %s -o %t +(* RUN: %ocamlc llvm.cma llvm_analysis.cma llvm_bitwriter.cma %s -o %t * RUN: ./%t %t.bc * RUN: llvm-dis < %t.bc > %t.ll *) @@ -467,7 +467,7 @@ let fn = define_function "Fn3" ty m in insist (not (is_declaration fn)); insist (1 = Array.length (basic_blocks fn)); - (* this function is not valid because init bb lacks a terminator *) + ignore (build_unreachable (builder_at_end (entry_block fn))); (* RUN: grep {define.*Fn4.*Param1.*Param2} < %t.ll *) @@ -481,7 +481,7 @@ insist (i64_type = type_of params.(1)); set_value_name "Param1" params.(0); set_value_name "Param2" params.(1); - (* this function is not valid because init bb lacks a terminator *) + ignore (build_unreachable (builder_at_end (entry_block fn))); (* RUN: grep {fastcc.*Fn5} < %t.ll *) @@ -489,7 +489,8 @@ let fn = define_function "Fn5" ty m in insist (ccc = function_call_conv fn); set_function_call_conv fastcc fn; - insist (fastcc = function_call_conv fn) + insist (fastcc = function_call_conv fn); + ignore (build_unreachable (builder_at_end (entry_block fn))) (*===-- Basic Blocks ------------------------------------------------------===*) @@ -503,6 +504,7 @@ let fn = declare_function "X" ty m in let bb = append_block "Bb1" fn in insist (bb = entry_block fn); + ignore (build_unreachable (builder_at_end bb)); (* RUN: grep -v Bb2 < %t.ll *) @@ -513,15 +515,18 @@ group "insert"; let fn = declare_function "X3" ty m in - let bbb = append_block "" fn in - let bba = insert_block "" bbb in + let bbb = append_block "b" fn in + let bba = insert_block "a" bbb in insist ([| bba; bbb |] = basic_blocks fn); + ignore (build_unreachable (builder_at_end bba)); + ignore (build_unreachable (builder_at_end bbb)); (* RUN: grep Bb3 < %t.ll *) group "name/value"; let fn = define_function "X4" ty m in let bb = entry_block fn in + ignore (build_unreachable (builder_at_end bb)); let bbv = value_of_block bb in set_value_name "Bb3" bbv; insist ("Bb3" = value_name bbv); @@ -529,6 +534,7 @@ group "casts"; let fn = define_function "X5" ty m in let bb = entry_block fn in + ignore (build_unreachable (builder_at_end bb)); insist (bb = block_of_value (value_of_block bb)); insist (value_is_block (value_of_block bb)); insist (not (value_is_block (const_null i32_type))) @@ -650,7 +656,8 @@ let inst16 = build_or p1 inst15 "Inst16" b in let inst17 = build_xor p1 inst16 "Inst17" b in let inst18 = build_neg inst17 "Inst18" b in - ignore (build_not inst18 "Inst19" b) + ignore (build_not inst18 "Inst19" b); + ignore (build_unreachable b) end; group "memory"; begin @@ -673,7 +680,8 @@ ignore(build_free inst20 b); ignore(build_load inst21 "Inst25" b); ignore(build_store p2 inst22 b); - ignore(build_gep inst23 [| p2 |] "Inst27" b) + ignore(build_gep inst23 [| p2 |] "Inst27" b); + ignore(build_unreachable b) end; group "casts"; begin @@ -724,11 +732,8 @@ * RUN: grep {Inst48.*va_arg.*null.*i32} < %t.ll * RUN: grep {Inst49.*extractelement.*Vec1.*P2} < %t.ll * RUN: grep {Inst50.*insertelement.*Vec1.*P1.*P2} < %t.ll - * RUN: grep {Inst51.*shufflevector.*Vec1.*Vec2.*Vec3} < %t.ll + * RUN: grep {Inst51.*shufflevector.*Vec1.*Vec2.*1.*1.*0.*0} < %t.ll *) - - (* TODO: %Inst44 = Phi *) - ignore (build_call fn [| p2; p1 |] "Inst45" atentry); let inst46 = build_icmp Icmp_eq p1 p2 "Inst46" atentry in ignore (build_select inst46 p1 p2 "Inst47" atentry); @@ -737,8 +742,8 @@ i32_type "Inst48" atentry); (* Set up some vector vregs. *) - let one = const_int i32_type (-1) in - let zero = const_int i32_type 1 in + let one = const_int i32_type 1 in + let zero = const_int i32_type 0 in let t1 = const_vector [| one; zero; one; zero |] in let t2 = const_vector [| zero; one; zero; one |] in let t3 = const_vector [| one; one; zero; zero |] in @@ -748,13 +753,38 @@ ignore (build_extractelement vec1 p2 "Inst49" atentry); ignore (build_insertelement vec1 p1 p2 "Inst50" atentry); - ignore (build_shufflevector vec1 vec2 vec3 "Inst51" atentry); + ignore (build_shufflevector vec1 vec2 t3 "Inst51" atentry); + end; + + group "phi"; begin + (* RUN: grep {PhiNode.*P1.*PhiBlock1.*P2.*PhiBlock2} < %t.ll + *) + let b1 = append_block "PhiBlock1" fn in + let b2 = append_block "PhiBlock2" fn in + + let jb = append_block "PhiJoinBlock" fn in + ignore (build_br jb (builder_at_end b1)); + ignore (build_br jb (builder_at_end b2)); + let at_jb = builder_at_end jb in + + let phi = build_phi [(p1, b1)] "PhiNode" at_jb in + insist ([(p1, b1)] = incoming phi); + + add_incoming (p2, b2) phi; + insist ([(p1, b1); (p2, b2)] = incoming phi); + + ignore (build_unreachable at_jb); end (*===-- Writer ------------------------------------------------------------===*) let test_writer () = + group "valid"; + insist (match Llvm_analysis.verify_module m with + | None -> true + | Some msg -> prerr_string msg; false); + group "writer"; insist (write_bitcode_file m filename); From evan.cheng at apple.com Mon Oct 8 13:27:46 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 08 Oct 2007 18:27:46 -0000 Subject: [llvm-commits] [test-suite] r42761 - /test-suite/trunk/Makefile.programs Message-ID: <200710081827.l98IRkD4001512@zion.cs.uiuc.edu> Author: evancheng Date: Mon Oct 8 13:27:46 2007 New Revision: 42761 URL: http://llvm.org/viewvc/llvm-project?rev=42761&view=rev Log: Allow x86 compare to be commutable by default. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=42761&r1=42760&r2=42761&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Mon Oct 8 13:27:46 2007 @@ -221,8 +221,7 @@ LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),x86) -LLCBETAOPTION := -enable-x86-commute-cmove -#-regalloc=local -fast +LLCBETAOPTION := -regalloc=local -fast #-disable-rematerialization #-disable-fp-elim #-regalloc=bigblock -fast From evan.cheng at apple.com Mon Oct 8 13:27:47 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 08 Oct 2007 18:27:47 -0000 Subject: [llvm-commits] [llvm] r42761 - /llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200710081827.l98IRlX2001517@zion.cs.uiuc.edu> Author: evancheng Date: Mon Oct 8 13:27:46 2007 New Revision: 42761 URL: http://llvm.org/viewvc/llvm-project?rev=42761&view=rev Log: Allow x86 compare to be commutable by default. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=42761&r1=42760&r2=42761&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon Oct 8 13:27:46 2007 @@ -22,15 +22,8 @@ #include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Support/CommandLine.h" using namespace llvm; -namespace { - cl::opt - EnableCommuteCMove("enable-x86-commute-cmove", - cl::desc("Commute conditional moves by inverting conditions")); -} - X86InstrInfo::X86InstrInfo(X86TargetMachine &tm) : TargetInstrInfo(X86Insts, array_lengthof(X86Insts)), TM(tm), RI(tm, *this) { @@ -442,8 +435,6 @@ case X86::CMOVNP16rr: case X86::CMOVNP32rr: case X86::CMOVNP64rr: { - if (!EnableCommuteCMove) - return 0; unsigned Opc = 0; switch (MI->getOpcode()) { default: break; From djg at cray.com Mon Oct 8 13:33:36 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 08 Oct 2007 18:33:36 -0000 Subject: [llvm-commits] [llvm] r42762 - in /llvm/trunk/lib: CodeGen/SelectionDAG/LegalizeDAG.cpp CodeGen/SelectionDAG/TargetLowering.cpp Target/ARM/ARMISelDAGToDAG.cpp Target/ARM/ARMISelLowering.cpp Target/ARM/ARMISelLowering.h Target/X86/X86ISelDAGToDAG.cpp Target/X86/X86ISelLowering.cpp Target/X86/X86ISelLowering.h Message-ID: <200710081833.l98IXaQL001733@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 8 13:33:35 2007 New Revision: 42762 URL: http://llvm.org/viewvc/llvm-project?rev=42762&view=rev Log: Migrate X86 and ARM from using X86ISD::{,I}DIV and ARMISD::MULHILO{U,S} to use ISD::{S,U}DIVREM and ISD::{S,U}MUL_HIO. Move the lowering code associated with these operators into target-independent in LegalizeDAG.cpp and TargetLowering.cpp. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=42762&r1=42761&r2=42762&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Oct 8 13:33:35 2007 @@ -2577,6 +2577,55 @@ if (Tmp1.Val) Result = Tmp1; break; case TargetLowering::Expand: { + MVT::ValueType VT = Op.getValueType(); + + // See if multiply or divide can be lowered using two-result operations. + SDVTList VTs = DAG.getVTList(VT, VT); + if (Node->getOpcode() == ISD::MUL) { + // We just need the low half of the multiply; try both the signed + // and unsigned forms. If the target supports both SMUL_LOHI and + // UMUL_LOHI, form a preference by checking which forms of plain + // MULH it supports. + bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, VT); + bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, VT); + bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, VT); + bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, VT); + unsigned OpToUse = 0; + if (HasSMUL_LOHI && !HasMULHS) { + OpToUse = ISD::SMUL_LOHI; + } else if (HasUMUL_LOHI && !HasMULHU) { + OpToUse = ISD::UMUL_LOHI; + } else if (HasSMUL_LOHI) { + OpToUse = ISD::SMUL_LOHI; + } else if (HasUMUL_LOHI) { + OpToUse = ISD::UMUL_LOHI; + } + if (OpToUse) { + Result = SDOperand(DAG.getNode(OpToUse, VTs, Tmp1, Tmp2).Val, 0); + break; + } + } + if (Node->getOpcode() == ISD::MULHS && + TLI.isOperationLegal(ISD::SMUL_LOHI, VT)) { + Result = SDOperand(DAG.getNode(ISD::SMUL_LOHI, VTs, Tmp1, Tmp2).Val, 1); + break; + } + if (Node->getOpcode() == ISD::MULHU && + TLI.isOperationLegal(ISD::UMUL_LOHI, VT)) { + Result = SDOperand(DAG.getNode(ISD::UMUL_LOHI, VTs, Tmp1, Tmp2).Val, 1); + break; + } + if (Node->getOpcode() == ISD::SDIV && + TLI.isOperationLegal(ISD::SDIVREM, VT)) { + Result = SDOperand(DAG.getNode(ISD::SDIVREM, VTs, Tmp1, Tmp2).Val, 0); + break; + } + if (Node->getOpcode() == ISD::UDIV && + TLI.isOperationLegal(ISD::UDIVREM, VT)) { + Result = SDOperand(DAG.getNode(ISD::UDIVREM, VTs, Tmp1, Tmp2).Val, 0); + break; + } + if (Node->getValueType(0) == MVT::i32) { switch (Node->getOpcode()) { default: assert(0 && "Do not know how to expand this integer BinOp!"); @@ -2638,6 +2687,10 @@ // they shouldn't be here if they aren't legal. assert(TLI.isOperationLegal(Node->getValueType(0), Node->getValueType(0)) && "This must be legal!"); + + Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS + Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS + Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); break; case ISD::FCOPYSIGN: // FCOPYSIGN does not require LHS/RHS to match type! @@ -2764,19 +2817,33 @@ if (Tmp1.Val) Result = Tmp1; } break; - case TargetLowering::Expand: + case TargetLowering::Expand: { unsigned DivOpc= (Node->getOpcode() == ISD::UREM) ? ISD::UDIV : ISD::SDIV; bool isSigned = DivOpc == ISD::SDIV; - if (MVT::isInteger(Node->getValueType(0))) { - if (TLI.getOperationAction(DivOpc, Node->getValueType(0)) == + MVT::ValueType VT = Node->getValueType(0); + + // See if remainder can be lowered using two-result operations. + SDVTList VTs = DAG.getVTList(VT, VT); + if (Node->getOpcode() == ISD::SREM && + TLI.isOperationLegal(ISD::SDIVREM, VT)) { + Result = SDOperand(DAG.getNode(ISD::SDIVREM, VTs, Tmp1, Tmp2).Val, 1); + break; + } + if (Node->getOpcode() == ISD::UREM && + TLI.isOperationLegal(ISD::UDIVREM, VT)) { + Result = SDOperand(DAG.getNode(ISD::UDIVREM, VTs, Tmp1, Tmp2).Val, 1); + break; + } + + if (MVT::isInteger(VT)) { + if (TLI.getOperationAction(DivOpc, VT) == TargetLowering::Legal) { // X % Y -> X-X/Y*Y - MVT::ValueType VT = Node->getValueType(0); Result = DAG.getNode(DivOpc, VT, Tmp1, Tmp2); Result = DAG.getNode(ISD::MUL, VT, Result, Tmp2); Result = DAG.getNode(ISD::SUB, VT, Tmp1, Result); } else { - assert(Node->getValueType(0) == MVT::i32 && + assert(VT == MVT::i32 && "Cannot expand this binary operator!"); RTLIB::Libcall LC = Node->getOpcode() == ISD::UREM ? RTLIB::UREM_I32 : RTLIB::SREM_I32; @@ -2785,7 +2852,7 @@ } } else { // Floating point mod -> fmod libcall. - RTLIB::Libcall LC = Node->getValueType(0) == MVT::f32 + RTLIB::Libcall LC = VT == MVT::f32 ? RTLIB::REM_F32 : RTLIB::REM_F64; SDOperand Dummy; Result = ExpandLibCall(TLI.getLibcallName(LC), Node, @@ -2793,6 +2860,7 @@ } break; } + } break; case ISD::VAARG: { Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. @@ -5666,36 +5734,55 @@ bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT); bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT); - if (HasMULHS || HasMULHU) { + bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT); + bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT); + if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) { SDOperand LL, LH, RL, RH; ExpandOp(Node->getOperand(0), LL, LH); ExpandOp(Node->getOperand(1), RL, RH); - unsigned SH = MVT::getSizeInBits(RH.getValueType())-1; - // FIXME: Move this to the dag combiner. - // MULHS implicitly sign extends its inputs. Check to see if ExpandOp - // extended the sign bit of the low half through the upper half, and if so - // emit a MULHS instead of the alternate sequence that is valid for any - // i64 x i64 multiply. - if (HasMULHS && - // is RH an extension of the sign bit of RL? - RH.getOpcode() == ISD::SRA && RH.getOperand(0) == RL && - RH.getOperand(1).getOpcode() == ISD::Constant && - cast(RH.getOperand(1))->getValue() == SH && - // is LH an extension of the sign bit of LL? - LH.getOpcode() == ISD::SRA && LH.getOperand(0) == LL && - LH.getOperand(1).getOpcode() == ISD::Constant && - cast(LH.getOperand(1))->getValue() == SH) { - // Low part: - Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); - // High part: - Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL); - break; - } else if (HasMULHU) { - // Low part: - Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); - - // High part: - Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); + unsigned BitSize = MVT::getSizeInBits(RH.getValueType()); + unsigned LHSSB = DAG.ComputeNumSignBits(Op.getOperand(0)); + unsigned RHSSB = DAG.ComputeNumSignBits(Op.getOperand(1)); + // FIXME: generalize this to handle other bit sizes + if (LHSSB == 32 && RHSSB == 32 && + DAG.MaskedValueIsZero(Op.getOperand(0), 0xFFFFFFFF00000000ULL) && + DAG.MaskedValueIsZero(Op.getOperand(1), 0xFFFFFFFF00000000ULL)) { + // The inputs are both zero-extended. + if (HasUMUL_LOHI) { + // We can emit a umul_lohi. + Lo = DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL); + Hi = SDOperand(Lo.Val, 1); + break; + } + if (HasMULHU) { + // We can emit a mulhu+mul. + Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); + Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); + break; + } + break; + } + if (LHSSB > BitSize && RHSSB > BitSize) { + // The input values are both sign-extended. + if (HasSMUL_LOHI) { + // We can emit a smul_lohi. + Lo = DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL); + Hi = SDOperand(Lo.Val, 1); + break; + } + if (HasMULHS) { + // We can emit a mulhs+mul. + Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); + Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL); + break; + } + } + if (HasUMUL_LOHI) { + // Lo,Hi = umul LHS, RHS. + SDOperand UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, + DAG.getVTList(NVT, NVT), LL, RL); + Lo = UMulLOHI; + Hi = UMulLOHI.getValue(1); RH = DAG.getNode(ISD::MUL, NVT, LL, RH); LH = DAG.getNode(ISD::MUL, NVT, LH, RL); Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); @@ -5704,6 +5791,7 @@ } } + // If nothing else, we can make a libcall. Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::MUL_I64), Node, false/*sign irrelevant*/, Hi); break; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=42762&r1=42761&r2=42762&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Mon Oct 8 13:33:35 2007 @@ -1706,15 +1706,21 @@ // Check to see if we can do this. if (!isTypeLegal(VT) || (VT != MVT::i32 && VT != MVT::i64)) return SDOperand(); // BuildSDIV only operates on i32 or i64 - if (!isOperationLegal(ISD::MULHS, VT)) - return SDOperand(); // Make sure the target supports MULHS. int64_t d = cast(N->getOperand(1))->getSignExtended(); ms magics = (VT == MVT::i32) ? magic32(d) : magic64(d); // Multiply the numerator (operand 0) by the magic value - SDOperand Q = DAG.getNode(ISD::MULHS, VT, N->getOperand(0), - DAG.getConstant(magics.m, VT)); + SDOperand Q; + if (isOperationLegal(ISD::MULHS, VT)) + Q = DAG.getNode(ISD::MULHS, VT, N->getOperand(0), + DAG.getConstant(magics.m, VT)); + else if (isOperationLegal(ISD::SMUL_LOHI, VT)) + Q = SDOperand(DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(VT, VT), + N->getOperand(0), + DAG.getConstant(magics.m, VT)).Val, 1); + else + return SDOperand(); // No mulhs or equvialent // If d > 0 and m < 0, add the numerator if (d > 0 && magics.m < 0) { Q = DAG.getNode(ISD::ADD, VT, Q, N->getOperand(0)); @@ -1754,15 +1760,21 @@ // Check to see if we can do this. if (!isTypeLegal(VT) || (VT != MVT::i32 && VT != MVT::i64)) return SDOperand(); // BuildUDIV only operates on i32 or i64 - if (!isOperationLegal(ISD::MULHU, VT)) - return SDOperand(); // Make sure the target supports MULHU. uint64_t d = cast(N->getOperand(1))->getValue(); mu magics = (VT == MVT::i32) ? magicu32(d) : magicu64(d); // Multiply the numerator (operand 0) by the magic value - SDOperand Q = DAG.getNode(ISD::MULHU, VT, N->getOperand(0), - DAG.getConstant(magics.m, VT)); + SDOperand Q; + if (isOperationLegal(ISD::MULHU, VT)) + Q = DAG.getNode(ISD::MULHU, VT, N->getOperand(0), + DAG.getConstant(magics.m, VT)); + else if (isOperationLegal(ISD::UMUL_LOHI, VT)) + Q = SDOperand(DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(VT, VT), + N->getOperand(0), + DAG.getConstant(magics.m, VT)).Val, 1); + else + return SDOperand(); // No mulhu or equvialent if (Created) Created->push_back(Q.Val); Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=42762&r1=42761&r2=42762&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Mon Oct 8 13:33:35 2007 @@ -641,7 +641,7 @@ return CurDAG->getTargetNode(ARM::FMRRD, MVT::i32, MVT::i32, Op.getOperand(0), getAL(CurDAG), CurDAG->getRegister(0, MVT::i32)); - case ARMISD::MULHILOU: { + case ISD::UMUL_LOHI: { AddToISelQueue(Op.getOperand(0)); AddToISelQueue(Op.getOperand(1)); SDOperand Ops[] = { Op.getOperand(0), Op.getOperand(1), @@ -649,7 +649,7 @@ CurDAG->getRegister(0, MVT::i32) }; return CurDAG->getTargetNode(ARM::UMULL, MVT::i32, MVT::i32, Ops, 5); } - case ARMISD::MULHILOS: { + case ISD::SMUL_LOHI: { AddToISelQueue(Op.getOperand(0)); AddToISelQueue(Op.getOperand(1)); SDOperand Ops[] = { Op.getOperand(0), Op.getOperand(1), Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=42762&r1=42761&r2=42762&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Oct 8 13:33:35 2007 @@ -147,11 +147,13 @@ setOperationAction(ISD::MUL, MVT::i64, Expand); setOperationAction(ISD::MULHU, MVT::i32, Expand); setOperationAction(ISD::MULHS, MVT::i32, Expand); + setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); + setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); } else { - setOperationAction(ISD::MUL, MVT::i64, Custom); - setOperationAction(ISD::MULHU, MVT::i32, Custom); + setOperationAction(ISD::MUL, MVT::i64, Expand); + setOperationAction(ISD::MULHU, MVT::i32, Expand); if (!Subtarget->hasV6Ops()) - setOperationAction(ISD::MULHS, MVT::i32, Custom); + setOperationAction(ISD::MULHS, MVT::i32, Expand); } setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); @@ -175,6 +177,8 @@ setOperationAction(ISD::UDIV, MVT::i32, Expand); setOperationAction(ISD::SREM, MVT::i32, Expand); setOperationAction(ISD::UREM, MVT::i32, Expand); + setOperationAction(ISD::SDIVREM, MVT::i32, Expand); + setOperationAction(ISD::UDIVREM, MVT::i32, Expand); // Support label based line numbers. setOperationAction(ISD::LOCATION, MVT::Other, Expand); @@ -286,8 +290,6 @@ case ARMISD::FTOUI: return "ARMISD::FTOUI"; case ARMISD::SITOF: return "ARMISD::SITOF"; case ARMISD::UITOF: return "ARMISD::UITOF"; - case ARMISD::MULHILOU: return "ARMISD::MULHILOU"; - case ARMISD::MULHILOS: return "ARMISD::MULHILOS"; case ARMISD::SRL_FLAG: return "ARMISD::SRL_FLAG"; case ARMISD::SRA_FLAG: return "ARMISD::SRA_FLAG"; @@ -1249,66 +1251,6 @@ return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Cvt, Cvt.getValue(1)); } -static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG) { - // FIXME: All this code is target-independent. Create a new target-indep - // MULHILO node and move this code to the legalizer. - // - assert(Op.getValueType() == MVT::i64 && "Only handles i64 expand right now!"); - - SDOperand LL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), - DAG.getConstant(0, MVT::i32)); - SDOperand RL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(1), - DAG.getConstant(0, MVT::i32)); - - unsigned LHSSB = DAG.ComputeNumSignBits(Op.getOperand(0)); - unsigned RHSSB = DAG.ComputeNumSignBits(Op.getOperand(1)); - - SDOperand Lo, Hi; - // Figure out how to lower this multiply. - if (LHSSB >= 33 && RHSSB >= 33) { - // If the input values are both sign extended, we can emit a mulhs+mul. - Lo = DAG.getNode(ISD::MUL, MVT::i32, LL, RL); - Hi = DAG.getNode(ISD::MULHS, MVT::i32, LL, RL); - } else if (LHSSB == 32 && RHSSB == 32 && - DAG.MaskedValueIsZero(Op.getOperand(0), 0xFFFFFFFF00000000ULL) && - DAG.MaskedValueIsZero(Op.getOperand(1), 0xFFFFFFFF00000000ULL)) { - // If the inputs are zero extended, use mulhu. - Lo = DAG.getNode(ISD::MUL, MVT::i32, LL, RL); - Hi = DAG.getNode(ISD::MULHU, MVT::i32, LL, RL); - } else { - SDOperand LH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), - DAG.getConstant(1, MVT::i32)); - SDOperand RH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(1), - DAG.getConstant(1, MVT::i32)); - - // Lo,Hi = umul LHS, RHS. - SDOperand Ops[] = { LL, RL }; - SDOperand UMul64 = DAG.getNode(ARMISD::MULHILOU, - DAG.getVTList(MVT::i32, MVT::i32), Ops, 2); - Lo = UMul64; - Hi = UMul64.getValue(1); - RH = DAG.getNode(ISD::MUL, MVT::i32, LL, RH); - LH = DAG.getNode(ISD::MUL, MVT::i32, LH, RL); - Hi = DAG.getNode(ISD::ADD, MVT::i32, Hi, RH); - Hi = DAG.getNode(ISD::ADD, MVT::i32, Hi, LH); - } - - // Merge the pieces into a single i64 value. - return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); -} - -static SDOperand LowerMULHU(SDOperand Op, SelectionDAG &DAG) { - SDOperand Ops[] = { Op.getOperand(0), Op.getOperand(1) }; - return DAG.getNode(ARMISD::MULHILOU, - DAG.getVTList(MVT::i32, MVT::i32), Ops, 2).getValue(1); -} - -static SDOperand LowerMULHS(SDOperand Op, SelectionDAG &DAG) { - SDOperand Ops[] = { Op.getOperand(0), Op.getOperand(1) }; - return DAG.getNode(ARMISD::MULHILOS, - DAG.getVTList(MVT::i32, MVT::i32), Ops, 2).getValue(1); -} - static SDOperand LowerSRx(SDOperand Op, SelectionDAG &DAG, const ARMSubtarget *ST) { assert(Op.getValueType() == MVT::i64 && @@ -1433,9 +1375,6 @@ case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG); case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); case ISD::BIT_CONVERT: return LowerBIT_CONVERT(Op, DAG); - case ISD::MUL: return LowerMUL(Op, DAG); - case ISD::MULHU: return LowerMULHU(Op, DAG); - case ISD::MULHS: return LowerMULHS(Op, DAG); case ISD::SRL: case ISD::SRA: return LowerSRx(Op, DAG, Subtarget); case ISD::FORMAL_ARGUMENTS: Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=42762&r1=42761&r2=42762&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Mon Oct 8 13:33:35 2007 @@ -56,9 +56,6 @@ SITOF, // sint to FP within a FP register. UITOF, // uint to FP within a FP register. - MULHILOU, // Lo,Hi = umul LHS, RHS. - MULHILOS, // Lo,Hi = smul LHS, RHS. - SRL_FLAG, // V,Flag = srl_flag X -> srl X, 1 + save carry out. SRA_FLAG, // V,Flag = sra_flag X -> sra X, 1 + save carry out. RRX, // V = RRX X, Flag -> srl X, 1 + shift in carry flag. Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=42762&r1=42761&r2=42762&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Mon Oct 8 13:33:35 2007 @@ -1085,9 +1085,22 @@ break; } - case ISD::MULHU: - case ISD::MULHS: { - if (Opcode == ISD::MULHU) + case ISD::SMUL_LOHI: + case ISD::UMUL_LOHI: { + SDOperand N0 = Node->getOperand(0); + SDOperand N1 = Node->getOperand(1); + + // There are several forms of IMUL just return the low part and don't + // have fixed-register operands. If we don't need the high part, use + // these instead. They can be selected with the generated ISel code. + if (NVT != MVT::i8 && + N.getValue(1).use_empty()) { + N = CurDAG->getNode(ISD::MUL, NVT, N0, N1); + break; + } + + bool isSigned = Opcode == ISD::SMUL_LOHI; + if (!isSigned) switch (NVT) { default: assert(0 && "Unsupported VT!"); case MVT::i8: Opc = X86::MUL8r; MOpc = X86::MUL8m; break; @@ -1113,78 +1126,90 @@ case MVT::i64: LoReg = X86::RAX; HiReg = X86::RDX; break; } - SDOperand N0 = Node->getOperand(0); - SDOperand N1 = Node->getOperand(1); - SDOperand Tmp0, Tmp1, Tmp2, Tmp3; bool foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3); - // MULHU and MULHS are commmutative + // multiplty is commmutative if (!foldedLoad) { foldedLoad = TryFoldLoad(N, N0, Tmp0, Tmp1, Tmp2, Tmp3); if (foldedLoad) std::swap(N0, N1); } - SDOperand Chain; - if (foldedLoad) { - Chain = N1.getOperand(0); - AddToISelQueue(Chain); - } else - Chain = CurDAG->getEntryNode(); - - SDOperand InFlag(0, 0); AddToISelQueue(N0); - Chain = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(LoReg, NVT), - N0, InFlag); - InFlag = Chain.getValue(1); + SDOperand InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), LoReg, + N0, SDOperand()).getValue(1); if (foldedLoad) { + AddToISelQueue(N1.getOperand(0)); AddToISelQueue(Tmp0); AddToISelQueue(Tmp1); AddToISelQueue(Tmp2); AddToISelQueue(Tmp3); - SDOperand Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Chain, InFlag }; + SDOperand Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, N1.getOperand(0), InFlag }; SDNode *CNode = CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Ops, 6); - Chain = SDOperand(CNode, 0); InFlag = SDOperand(CNode, 1); + // Update the chain. + ReplaceUses(N1.getValue(1), SDOperand(CNode, 0)); } else { AddToISelQueue(N1); InFlag = SDOperand(CurDAG->getTargetNode(Opc, MVT::Flag, N1, InFlag), 0); } - SDOperand Result; - if (HiReg == X86::AH && Subtarget->is64Bit()) { - // Prevent use of AH in a REX instruction by referencing AX instead. - // Shift it down 8 bits. - Result = CurDAG->getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag); - Chain = Result.getValue(1); - Result = SDOperand(CurDAG->getTargetNode(X86::SHR16ri, MVT::i16, Result, - CurDAG->getTargetConstant(8, MVT::i8)), 0); - // Then truncate it down to i8. - SDOperand SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1 - Result = SDOperand(CurDAG->getTargetNode(X86::EXTRACT_SUBREG, - MVT::i8, Result, SRIdx), 0); - } else { - Result = CurDAG->getCopyFromReg(Chain, HiReg, NVT, InFlag); + // Copy the low half of the result, if it is needed. + if (!N.getValue(0).use_empty()) { + SDOperand Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), + LoReg, NVT, InFlag); + InFlag = Result.getValue(2); + ReplaceUses(N.getValue(0), Result); +#ifndef NDEBUG + DOUT << std::string(Indent-2, ' ') << "=> "; + DEBUG(Result.Val->dump(CurDAG)); + DOUT << "\n"; +#endif + } + // Copy the high half of the result, if it is needed. + if (!N.getValue(1).use_empty()) { + SDOperand Result; + if (HiReg == X86::AH && Subtarget->is64Bit()) { + // Prevent use of AH in a REX instruction by referencing AX instead. + // Shift it down 8 bits. + Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), + X86::AX, MVT::i16, InFlag); + InFlag = Result.getValue(2); + Result = SDOperand(CurDAG->getTargetNode(X86::SHR16ri, MVT::i16, Result, + CurDAG->getTargetConstant(8, MVT::i8)), 0); + // Then truncate it down to i8. + SDOperand SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1 + Result = SDOperand(CurDAG->getTargetNode(X86::EXTRACT_SUBREG, + MVT::i8, Result, SRIdx), 0); + } else { + Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), + HiReg, NVT, InFlag); + InFlag = Result.getValue(2); + } + ReplaceUses(N.getValue(1), Result); +#ifndef NDEBUG + DOUT << std::string(Indent-2, ' ') << "=> "; + DEBUG(Result.Val->dump(CurDAG)); + DOUT << "\n"; +#endif } - ReplaceUses(N.getValue(0), Result); - if (foldedLoad) - ReplaceUses(N1.getValue(1), Result.getValue(1)); #ifndef NDEBUG - DOUT << std::string(Indent-2, ' ') << "=> "; - DEBUG(Result.Val->dump(CurDAG)); - DOUT << "\n"; Indent -= 2; #endif + return NULL; } - case X86ISD::DIV: - case X86ISD::IDIV: { - bool isSigned = Opcode == X86ISD::IDIV; + case ISD::SDIVREM: + case ISD::UDIVREM: { + SDOperand N0 = Node->getOperand(0); + SDOperand N1 = Node->getOperand(1); + + bool isSigned = Opcode == ISD::SDIVREM; if (!isSigned) switch (NVT) { default: assert(0 && "Unsupported VT!"); @@ -1228,9 +1253,10 @@ break; } - SDOperand N0 = Node->getOperand(0); - SDOperand N1 = Node->getOperand(1); - SDOperand InFlag(0, 0); + SDOperand Tmp0, Tmp1, Tmp2, Tmp3; + bool foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3); + + SDOperand InFlag; if (NVT == MVT::i8 && !isSigned) { // Special case for div8, just use a move with zero extension to AX to // clear the upper 8 bits (AH). @@ -1253,13 +1279,13 @@ SDOperand(CurDAG->getTargetNode(X86::MOVZX16rr8, MVT::i16, N0), 0); Chain = CurDAG->getEntryNode(); } - Chain = CurDAG->getCopyToReg(Chain, X86::AX, Move, InFlag); + Chain = CurDAG->getCopyToReg(Chain, X86::AX, Move, SDOperand()); InFlag = Chain.getValue(1); } else { AddToISelQueue(N0); InFlag = - CurDAG->getCopyToReg(CurDAG->getEntryNode(), LoReg, N0, - InFlag).getValue(1); + CurDAG->getCopyToReg(CurDAG->getEntryNode(), + LoReg, N0, SDOperand()).getValue(1); if (isSigned) { // Sign extend the low part into the high part. InFlag = @@ -1267,13 +1293,11 @@ } else { // Zero out the high part, effectively zero extending the input. SDOperand ClrNode = SDOperand(CurDAG->getTargetNode(ClrOpcode, NVT), 0); - InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), HiReg, ClrNode, - InFlag).getValue(1); + InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), HiReg, + ClrNode, InFlag).getValue(1); } } - SDOperand Tmp0, Tmp1, Tmp2, Tmp3, Chain; - bool foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3); if (foldedLoad) { AddToISelQueue(N1.getOperand(0)); AddToISelQueue(Tmp0); @@ -1283,19 +1307,19 @@ SDOperand Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, N1.getOperand(0), InFlag }; SDNode *CNode = CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Ops, 6); - Chain = SDOperand(CNode, 0); InFlag = SDOperand(CNode, 1); + // Update the chain. + ReplaceUses(N1.getValue(1), SDOperand(CNode, 0)); } else { AddToISelQueue(N1); - Chain = CurDAG->getEntryNode(); InFlag = SDOperand(CurDAG->getTargetNode(Opc, MVT::Flag, N1, InFlag), 0); } // Copy the division (low) result, if it is needed. if (!N.getValue(0).use_empty()) { - SDOperand Result = CurDAG->getCopyFromReg(Chain, LoReg, NVT, InFlag); - Chain = Result.getValue(1); + SDOperand Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), + LoReg, NVT, InFlag); InFlag = Result.getValue(2); ReplaceUses(N.getValue(0), Result); #ifndef NDEBUG @@ -1310,8 +1334,8 @@ if (HiReg == X86::AH && Subtarget->is64Bit()) { // Prevent use of AH in a REX instruction by referencing AX instead. // Shift it down 8 bits. - Result = CurDAG->getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag); - Chain = Result.getValue(1); + Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), + X86::AX, MVT::i16, InFlag); InFlag = Result.getValue(2); Result = SDOperand(CurDAG->getTargetNode(X86::SHR16ri, MVT::i16, Result, CurDAG->getTargetConstant(8, MVT::i8)), 0); @@ -1320,8 +1344,8 @@ Result = SDOperand(CurDAG->getTargetNode(X86::EXTRACT_SUBREG, MVT::i8, Result, SRIdx), 0); } else { - Result = CurDAG->getCopyFromReg(Chain, HiReg, NVT, InFlag); - Chain = Result.getValue(1); + Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), + HiReg, NVT, InFlag); InFlag = Result.getValue(2); } ReplaceUses(N.getValue(1), Result); @@ -1331,8 +1355,6 @@ DOUT << "\n"; #endif } - if (foldedLoad) - ReplaceUses(N1.getValue(1), Chain); #ifndef NDEBUG Indent -= 2; Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=42762&r1=42761&r2=42762&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Oct 8 13:33:35 2007 @@ -154,26 +154,41 @@ setOperationAction(ISD::BIT_CONVERT , MVT::i32 , Expand); } - // Divide and remainder are lowered to use div or idiv in legalize in - // order to expose the intermediate computations to trivial CSE. This is - // most noticeable when both x/y and x%y are being computed; they can be - // done with a single div or idiv. - setOperationAction(ISD::SDIV , MVT::i8 , Custom); - setOperationAction(ISD::UDIV , MVT::i8 , Custom); - setOperationAction(ISD::SREM , MVT::i8 , Custom); - setOperationAction(ISD::UREM , MVT::i8 , Custom); - setOperationAction(ISD::SDIV , MVT::i16 , Custom); - setOperationAction(ISD::UDIV , MVT::i16 , Custom); - setOperationAction(ISD::SREM , MVT::i16 , Custom); - setOperationAction(ISD::UREM , MVT::i16 , Custom); - setOperationAction(ISD::SDIV , MVT::i32 , Custom); - setOperationAction(ISD::UDIV , MVT::i32 , Custom); - setOperationAction(ISD::SREM , MVT::i32 , Custom); - setOperationAction(ISD::UREM , MVT::i32 , Custom); - setOperationAction(ISD::SDIV , MVT::i64 , Custom); - setOperationAction(ISD::UDIV , MVT::i64 , Custom); - setOperationAction(ISD::SREM , MVT::i64 , Custom); - setOperationAction(ISD::UREM , MVT::i64 , Custom); + // Scalar integer multiply, multiply-high, divide, and remainder are + // lowered to use operations that produce two results, to match the + // available instructions. This exposes the two-result form to trivial + // CSE, which is able to combine x/y and x%y into a single instruction, + // for example. The single-result multiply instructions are introduced + // in X86ISelDAGToDAG.cpp, after CSE, for uses where the the high part + // is not needed. + setOperationAction(ISD::MUL , MVT::i8 , Expand); + setOperationAction(ISD::MULHS , MVT::i8 , Expand); + setOperationAction(ISD::MULHU , MVT::i8 , Expand); + setOperationAction(ISD::SDIV , MVT::i8 , Expand); + setOperationAction(ISD::UDIV , MVT::i8 , Expand); + setOperationAction(ISD::SREM , MVT::i8 , Expand); + setOperationAction(ISD::UREM , MVT::i8 , Expand); + setOperationAction(ISD::MUL , MVT::i16 , Expand); + setOperationAction(ISD::MULHS , MVT::i16 , Expand); + setOperationAction(ISD::MULHU , MVT::i16 , Expand); + setOperationAction(ISD::SDIV , MVT::i16 , Expand); + setOperationAction(ISD::UDIV , MVT::i16 , Expand); + setOperationAction(ISD::SREM , MVT::i16 , Expand); + setOperationAction(ISD::UREM , MVT::i16 , Expand); + setOperationAction(ISD::MUL , MVT::i32 , Expand); + setOperationAction(ISD::MULHS , MVT::i32 , Expand); + setOperationAction(ISD::MULHU , MVT::i32 , Expand); + setOperationAction(ISD::SDIV , MVT::i32 , Expand); + setOperationAction(ISD::UDIV , MVT::i32 , Expand); + setOperationAction(ISD::SREM , MVT::i32 , Expand); + setOperationAction(ISD::UREM , MVT::i32 , Expand); + setOperationAction(ISD::MUL , MVT::i64 , Expand); + setOperationAction(ISD::MULHS , MVT::i64 , Expand); + setOperationAction(ISD::MULHU , MVT::i64 , Expand); + setOperationAction(ISD::SDIV , MVT::i64 , Expand); + setOperationAction(ISD::UDIV , MVT::i64 , Expand); + setOperationAction(ISD::SREM , MVT::i64 , Expand); + setOperationAction(ISD::UREM , MVT::i64 , Expand); setOperationAction(ISD::BR_JT , MVT::Other, Expand); setOperationAction(ISD::BRCOND , MVT::Other, Custom); @@ -449,6 +464,10 @@ setOperationAction(ISD::FPOWI, (MVT::ValueType)VT, Expand); setOperationAction(ISD::FSQRT, (MVT::ValueType)VT, Expand); setOperationAction(ISD::FCOPYSIGN, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::SMUL_LOHI, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::UMUL_LOHI, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::SDIVREM, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::UDIVREM, (MVT::ValueType)VT, Expand); } if (Subtarget->hasMMX()) { @@ -3398,22 +3417,6 @@ return DAG.getNode(ISD::MERGE_VALUES, VTs, 2, &Ops[0], Ops.size()); } -SDOperand X86TargetLowering::LowerIntegerDivOrRem(SDOperand Op, SelectionDAG &DAG) { - unsigned Opcode = Op.getOpcode(); - MVT::ValueType NVT = Op.getValueType(); - bool isSigned = Opcode == ISD::SDIV || Opcode == ISD::SREM; - bool isDiv = Opcode == ISD::SDIV || Opcode == ISD::UDIV; - unsigned Opc = isSigned ? X86ISD::IDIV : X86ISD::DIV; - - SDOperand Ops[] = { Op.getOperand(0), Op.getOperand(1) }; - SDOperand DR = DAG.getNode(Opc, DAG.getVTList(NVT, NVT), Ops, 2); - - if (isDiv) - return DR; - - return SDOperand(DR.Val, 1); -} - SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) { assert(Op.getOperand(0).getValueType() <= MVT::i64 && Op.getOperand(0).getValueType() >= MVT::i16 && @@ -4545,10 +4548,6 @@ case ISD::SHL_PARTS: case ISD::SRA_PARTS: case ISD::SRL_PARTS: return LowerShift(Op, DAG); - case ISD::SDIV: - case ISD::UDIV: - case ISD::SREM: - case ISD::UREM: return LowerIntegerDivOrRem(Op, DAG); case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG); case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG); case ISD::FABS: return LowerFABS(Op, DAG); @@ -4620,8 +4619,6 @@ case X86ISD::TLSADDR: return "X86ISD::TLSADDR"; case X86ISD::THREAD_POINTER: return "X86ISD::THREAD_POINTER"; case X86ISD::EH_RETURN: return "X86ISD::EH_RETURN"; - case X86ISD::DIV: return "X86ISD::DIV"; - case X86ISD::IDIV: return "X86ISD::IDIV"; } } Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=42762&r1=42761&r2=42762&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Oct 8 13:33:35 2007 @@ -177,10 +177,6 @@ /// in order to obtain suitable precision. FRSQRT, FRCP, - /// DIV, IDIV - Unsigned and signed integer division and remainder. - /// - DIV, IDIV, - // Thread Local Storage TLSADDR, THREAD_POINTER, From sabre at nondot.org Mon Oct 8 13:42:46 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 08 Oct 2007 18:42:46 -0000 Subject: [llvm-commits] [llvm] r42763 - /llvm/trunk/docs/BitCodeFormat.html Message-ID: <200710081842.l98Igk0c002082@zion.cs.uiuc.edu> Author: lattner Date: Mon Oct 8 13:42:45 2007 New Revision: 42763 URL: http://llvm.org/viewvc/llvm-project?rev=42763&view=rev Log: Various improvements to the documentation, contributed by Joshua Haberman! Modified: llvm/trunk/docs/BitCodeFormat.html Modified: llvm/trunk/docs/BitCodeFormat.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/BitCodeFormat.html?rev=42763&r1=42762&r2=42763&view=diff ============================================================================== --- llvm/trunk/docs/BitCodeFormat.html (original) +++ llvm/trunk/docs/BitCodeFormat.html Mon Oct 8 13:42:45 2007 @@ -29,7 +29,8 @@

-

Written by Chris Lattner. +

Written by Chris Lattner + and Joshua Haberman.

@@ -105,8 +106,10 @@
-

The first four bytes of the stream identify the encoding of the file. This -is used by a reader to know what is contained in the file.

+

The first two bytes of a bitcode file are 'BC' (0x42, 0x43). +The second two bytes are an application-specific magic number. Generic +bitcode tools can look at only the first two bytes to verify the file is +bitcode, while application-specific programs will want to look at all four.

@@ -117,7 +120,8 @@

-A bitstream literally consists of a stream of bits. This stream is made up of a +A bitstream literally consists of a stream of bits, which are read in order +starting with the least significant bit of each byte. The stream is made up of a number of primitive values that encode a stream of unsigned integer values. These integers are are encoded in two ways: either as Fixed @@ -172,8 +176,8 @@

@@ -240,7 +244,9 @@

Blocks in a bitstream denote nested regions of the stream, and are identified by a content-specific id number (for example, LLVM IR uses an ID of 12 to represent -function bodies). Nested blocks capture the hierachical structure of the data +function bodies). Block IDs 0-7 are reserved for standard blocks +whose meaning is defined by Bitcode; block IDs 8 and greater are +application specific. Nested blocks capture the hierachical structure of the data encoded in it, and various properties are associated with blocks as the file is parsed. Block definitions allow the reader to efficiently skip blocks in constant time if the reader wants a summary of blocks, or if it wants to @@ -258,8 +264,11 @@ block record is entered. The block entry specifies the abbrev id width for the body of the block. -

  • A set of abbreviations. Abbreviations may be defined within a block, or - they may be associated with all blocks of a particular ID. +
  • A set of abbreviations. Abbreviations may be defined within a block, in + which case they are only defined in that block (neither subblocks nor + enclosing blocks see the abbreviation). Abbreviations can also be defined + inside a BLOCKINFO block, in which case they are + defined in all blocks that match the ID that the BLOCKINFO block is describing.
  • @@ -281,7 +290,8 @@

    The ENTER_SUBBLOCK abbreviation ID specifies the start of a new block record. The blockid value is encoded as a 8-bit VBR identifier, and indicates -the type of block being entered (which is application specific). The +the type of block being entered (which can be a standard +block or an application-specific block). The newabbrevlen value is a 4-bit VBR which specifies the abbrev id width for the sub-block. The blocklen is a 32-bit aligned value that specifies the size of the subblock, in 32-bit words. This value @@ -397,6 +407,17 @@

    [DEFINE_ABBREV, numabbrevopsvbr5, abbrevop0, abbrevop1, ...]

    +

    A DEFINE_ABBREV record adds an abbreviation to the list of currently +defined abbreviations in the scope of this block. This definition only +exists inside this immediate block -- it is not visible in subblocks or +enclosing blocks. +Abbreviations are implicitly assigned IDs +sequentially starting from 4 (the first application-defined abbreviation ID). +Any abbreviations defined in a BLOCKINFO record receive IDs first, in order, +followed by any abbreviations defined within the block itself. +Abbreviated data records reference this ID to indicate what abbreviation +they are invoking.

    +

    An abbreviation definition consists of the DEFINE_ABBREV abbrevid followed by a VBR that specifies the number of abbrev operands, then the abbrev operands themselves. Abbreviation operands come in three forms. They all start @@ -422,14 +443,19 @@

    • 1 - Fixed - The field should be emitted as a fixed-width value, whose width - is specified by the encoding operand.
    • + is specified by the operand's extra data.
    • 2 - VBR - The field should be emitted as a variable-width value, whose width - is specified by the encoding operand.
    • -
    • 3 - Array - This field is an array of values. The element type of the array - is specified by the next encoding operand.
    • + is specified by the operand's extra data. +
    • 3 - Array - This field is an array of values. The array operand has no + extra data, but expects another operand to follow it which indicates the + element type of the array. When reading an array in an abbreviated record, + the first integer is a vbr6 that indicates the array length, followed by + the encoded elements of the array. An array may only occur as the last + operand of an abbreviation (except for the one final operand that gives + the array's type).
    • 4 - Char6 - This field should be emitted as a char6-encoded - value.
    • + value. This operand type takes no extra data.

    For example, target triples in LLVM modules are encoded as a record of the @@ -476,7 +502,7 @@ In addition to the basic block structure and record encodings, the bitstream also defines specific builtin block types. These block types specify how the stream is to be decoded or other metadata. In the future, new standard blocks -may be added. +may be added. Block IDs 0-7 are reserved for standard blocks.

    @@ -496,10 +522,24 @@

    -The SETBID record indicates which block ID is being described. The standard -DEFINE_ABBREV record specifies an abbreviation. The abbreviation is associated -with the record ID, and any records with matching ID automatically get the -abbreviation. +The SETBID record indicates which block ID is being described. SETBID +records can occur multiple times throughout the block to change which +block ID is being described. There must be a SETBID record prior to +any other records. +

    + +

    +Standard DEFINE_ABBREV records can occur inside BLOCKINFO blocks, but unlike +their occurrence in normal blocks, the abbreviation is defined for blocks +matching the block ID we are describing, not the BLOCKINFO block itself. +The abbreviations defined in BLOCKINFO blocks receive abbreviation ids +as described in DEFINE_ABBREV. +

    + +

    +Note that although the data in BLOCKINFO blocks is described as "metadata," the +abbreviations they contain are essential for parsing records from the +corresponding blocks. It is not safe to skip them.

    @@ -532,10 +572,9 @@ The magic number for LLVM IR files is:

    -

    ['B'8, 'C'8, 0x04, 0xC4, -0xE4, 0xD4]

    +

    [0x04, 0xC4, 0xE4, 0xD4]

    -

    When viewed as bytes, this is "BC 0xC0DE".

    +

    When combined with the bitcode magic number and viewed as bytes, this is "BC 0xC0DE".

    From djg at cray.com Mon Oct 8 15:48:13 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 08 Oct 2007 20:48:13 -0000 Subject: [llvm-commits] [llvm] r42765 - in /llvm/trunk/test/CodeGen/X86: mul128.ll mul64.ll Message-ID: <200710082048.l98KmDlB006656@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 8 15:48:12 2007 New Revision: 42765 URL: http://llvm.org/viewvc/llvm-project?rev=42765&view=rev Log: These two tests now require only three multiply instructions, instead of four. Added: llvm/trunk/test/CodeGen/X86/mul128.ll llvm/trunk/test/CodeGen/X86/mul64.ll Added: llvm/trunk/test/CodeGen/X86/mul128.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/mul128.ll?rev=42765&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/mul128.ll (added) +++ llvm/trunk/test/CodeGen/X86/mul128.ll Mon Oct 8 15:48:12 2007 @@ -0,0 +1,6 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | grep mul | count 3 + +define i128 @foo(i128 %t, i128 %u) { + %k = mul i128 %t, %u + ret i128 %k +} Added: llvm/trunk/test/CodeGen/X86/mul64.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/mul64.ll?rev=42765&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/mul64.ll (added) +++ llvm/trunk/test/CodeGen/X86/mul64.ll Mon Oct 8 15:48:12 2007 @@ -0,0 +1,6 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep mul | count 3 + +define i64 @foo(i64 %t, i64 %u) { + %k = mul i64 %t, %u + ret i64 %k +} From djg at cray.com Mon Oct 8 16:15:07 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 08 Oct 2007 21:15:07 -0000 Subject: [llvm-commits] [llvm] r42768 - /llvm/trunk/include/llvm/Intrinsics.td Message-ID: <200710082115.l98LF7H7008063@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 8 16:15:07 2007 New Revision: 42768 URL: http://llvm.org/viewvc/llvm-project?rev=42768&view=rev Log: Mark the prefetch intrinsic as IntrWriteArgMem, instead of the default of IntrWriteMem, to at least indicate that it doesn't "capture" the argument pointer. Modified: llvm/trunk/include/llvm/Intrinsics.td Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=42768&r1=42767&r2=42768&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Mon Oct 8 16:15:07 2007 @@ -153,8 +153,12 @@ GCCBuiltin<"__builtin_stack_save">; def int_stackrestore : Intrinsic<[llvm_void_ty, llvm_ptr_ty]>, GCCBuiltin<"__builtin_stack_restore">; +// IntrWriteArgMem is more pessimistic than strictly necessary for prefetch, +// however it does conveniently prevent the prefetch from being reordered +// with respect to nearby accesses to the same memory. def int_prefetch : Intrinsic<[llvm_void_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty]>; + llvm_i32_ty, llvm_i32_ty], + [IntrWriteArgMem]>; def int_pcmarker : Intrinsic<[llvm_void_ty, llvm_i32_ty]>; def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>; From djg at cray.com Mon Oct 8 16:27:13 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 08 Oct 2007 21:27:13 -0000 Subject: [llvm-commits] [llvm] r42769 - /llvm/trunk/lib/CodeGen/AsmPrinter.cpp Message-ID: <200710082127.l98LRD9C008514@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 8 16:27:12 2007 New Revision: 42769 URL: http://llvm.org/viewvc/llvm-project?rev=42769&view=rev Log: Call getFunctionNumber() instead of referencing FunctionNumber directly, for consistency. Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter.cpp?rev=42769&r1=42768&r2=42769&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Mon Oct 8 16:27:12 2007 @@ -1209,7 +1209,7 @@ void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB, bool printColon, bool printComment) const { - O << TAI->getPrivateGlobalPrefix() << "BB" << FunctionNumber << "_" + O << TAI->getPrivateGlobalPrefix() << "BB" << getFunctionNumber() << "_" << MBB->getNumber(); if (printColon) O << ':'; From evan.cheng at apple.com Mon Oct 8 17:16:29 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 08 Oct 2007 22:16:29 -0000 Subject: [llvm-commits] [llvm] r42774 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200710082216.l98MGTOX010154@zion.cs.uiuc.edu> Author: evancheng Date: Mon Oct 8 17:16:29 2007 New Revision: 42774 URL: http://llvm.org/viewvc/llvm-project?rev=42774&view=rev Log: Bug fix. X86 was emitting redundant setcc and test instructions before a conditional move. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=42774&r1=42773&r2=42774&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Oct 8 17:16:29 2007 @@ -3705,33 +3705,30 @@ if (Cond.getOpcode() == ISD::SETCC) Cond = LowerSETCC(Cond, DAG); + // If condition flag is set by a X86ISD::CMP, then use it as the condition + // setting operand in place of the X86ISD::SETCC. if (Cond.getOpcode() == X86ISD::SETCC) { CC = Cond.getOperand(0); - // If condition flag is set by a X86ISD::CMP, then make a copy of it - // (since flag operand cannot be shared). Use it as the condition setting - // operand in place of the X86ISD::SETCC. - // If the X86ISD::SETCC has more than one use, then perhaps it's better - // to use a test instead of duplicating the X86ISD::CMP (for register - // pressure reason)? SDOperand Cmp = Cond.getOperand(1); unsigned Opc = Cmp.getOpcode(); - bool IllegalFPCMov = - ! ((X86ScalarSSEf32 && Op.getValueType()==MVT::f32) || - (X86ScalarSSEf64 && Op.getValueType()==MVT::f64)) && - !hasFPCMov(cast(CC)->getSignExtended()); + MVT::ValueType VT = Op.getValueType(); + bool IllegalFPCMov = false; + if (VT == MVT::f32 && !X86ScalarSSEf32) + IllegalFPCMov = !hasFPCMov(cast(CC)->getSignExtended()); + else if (VT == MVT::f64 && !X86ScalarSSEf64) + IllegalFPCMov = !hasFPCMov(cast(CC)->getSignExtended()); if ((Opc == X86ISD::CMP || Opc == X86ISD::COMI || Opc == X86ISD::UCOMI) && !IllegalFPCMov) { - Cond = DAG.getNode(Opc, MVT::i32, Cmp.getOperand(0), Cmp.getOperand(1)); + Cond = Cmp; addTest = false; } } if (addTest) { CC = DAG.getConstant(X86::COND_NE, MVT::i8); - Cond = DAG.getNode(X86ISD::CMP, MVT::i32, Cond, - DAG.getConstant(0, MVT::i8)); + Cond= DAG.getNode(X86ISD::CMP, MVT::i32, Cond, DAG.getConstant(0, MVT::i8)); } const MVT::ValueType *VTs = DAG.getNodeValueTypes(Op.getValueType(), @@ -3756,21 +3753,17 @@ if (Cond.getOpcode() == ISD::SETCC) Cond = LowerSETCC(Cond, DAG); + // If condition flag is set by a X86ISD::CMP, then use it as the condition + // setting operand in place of the X86ISD::SETCC. if (Cond.getOpcode() == X86ISD::SETCC) { CC = Cond.getOperand(0); - // If condition flag is set by a X86ISD::CMP, then make a copy of it - // (since flag operand cannot be shared). Use it as the condition setting - // operand in place of the X86ISD::SETCC. - // If the X86ISD::SETCC has more than one use, then perhaps it's better - // to use a test instead of duplicating the X86ISD::CMP (for register - // pressure reason)? SDOperand Cmp = Cond.getOperand(1); unsigned Opc = Cmp.getOpcode(); if (Opc == X86ISD::CMP || Opc == X86ISD::COMI || Opc == X86ISD::UCOMI) { - Cond = DAG.getNode(Opc, MVT::i32, Cmp.getOperand(0), Cmp.getOperand(1)); + Cond = Cmp; addTest = false; } } From evan.cheng at apple.com Mon Oct 8 17:20:32 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 08 Oct 2007 22:20:32 -0000 Subject: [llvm-commits] [llvm] r42775 - /llvm/trunk/test/CodeGen/X86/select.ll Message-ID: <200710082220.l98MKWsU010293@zion.cs.uiuc.edu> Author: evancheng Date: Mon Oct 8 17:20:32 2007 New Revision: 42775 URL: http://llvm.org/viewvc/llvm-project?rev=42775&view=rev Log: Update test. Modified: llvm/trunk/test/CodeGen/X86/select.ll Modified: llvm/trunk/test/CodeGen/X86/select.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/select.ll?rev=42775&r1=42774&r2=42775&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/select.ll (original) +++ llvm/trunk/test/CodeGen/X86/select.ll Mon Oct 8 17:20:32 2007 @@ -1,64 +1,63 @@ -; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86 -mcpu=yonah -; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86 -mcpu=pentium +; RUN: llvm-as < %s | llc -march=x86 -mcpu=pentium +; RUN: llvm-as < %s | llc -march=x86 -mcpu=yonah +; RUN: llvm-as < %s | llc -march=x86 -mcpu=yonah | not grep set -bool %boolSel(bool %A, bool %B, bool %C) { - %X = select bool %A, bool %B, bool %C - ret bool %X +define i1 @boolSel(i1 %A, i1 %B, i1 %C) { + %X = select i1 %A, i1 %B, i1 %C ; [#uses=1] + ret i1 %X } -sbyte %byteSel(bool %A, sbyte %B, sbyte %C) { - %X = select bool %A, sbyte %B, sbyte %C - ret sbyte %X +define i8 @byteSel(i1 %A, i8 %B, i8 %C) { + %X = select i1 %A, i8 %B, i8 %C ; [#uses=1] + ret i8 %X } -short %shortSel(bool %A, short %B, short %C) { - %X = select bool %A, short %B, short %C - ret short %X +define i16 @shortSel(i1 %A, i16 %B, i16 %C) { + %X = select i1 %A, i16 %B, i16 %C ; [#uses=1] + ret i16 %X } -int %intSel(bool %A, int %B, int %C) { - %X = select bool %A, int %B, int %C - ret int %X +define i32 @intSel(i1 %A, i32 %B, i32 %C) { + %X = select i1 %A, i32 %B, i32 %C ; [#uses=1] + ret i32 %X } -long %longSel(bool %A, long %B, long %C) { - %X = select bool %A, long %B, long %C - ret long %X +define i64 @longSel(i1 %A, i64 %B, i64 %C) { + %X = select i1 %A, i64 %B, i64 %C ; [#uses=1] + ret i64 %X } -double %doubleSel(bool %A, double %B, double %C) { - %X = select bool %A, double %B, double %C +define double @doubleSel(i1 %A, double %B, double %C) { + %X = select i1 %A, double %B, double %C ; [#uses=1] ret double %X } -sbyte %foldSel(bool %A, sbyte %B, sbyte %C) { - %Cond = setlt sbyte %B, %C - %X = select bool %Cond, sbyte %B, sbyte %C - ret sbyte %X +define i8 @foldSel(i1 %A, i8 %B, i8 %C) { + %Cond = icmp slt i8 %B, %C ; [#uses=1] + %X = select i1 %Cond, i8 %B, i8 %C ; [#uses=1] + ret i8 %X } -int %foldSel2(bool %A, int %B, int %C) { - %Cond = seteq int %B, %C - %X = select bool %Cond, int %B, int %C - ret int %X +define i32 @foldSel2(i1 %A, i32 %B, i32 %C) { + %Cond = icmp eq i32 %B, %C ; [#uses=1] + %X = select i1 %Cond, i32 %B, i32 %C ; [#uses=1] + ret i32 %X } -int %foldSel2a(bool %A, int %B, int %C, double %X, double %Y) { - %Cond = setlt double %X, %Y - %X = select bool %Cond, int %B, int %C - ret int %X +define i32 @foldSel2a(i1 %A, i32 %B, i32 %C, double %X, double %Y) { + %Cond = fcmp olt double %X, %Y ; [#uses=1] + %X.upgrd.1 = select i1 %Cond, i32 %B, i32 %C ; [#uses=1] + ret i32 %X.upgrd.1 } -float %foldSel3(bool %A, float %B, float %C, uint %X, uint %Y) { - %Cond = setlt uint %X, %Y - %X = select bool %Cond, float %B, float %C - ret float %X +define float @foldSel3(i1 %A, float %B, float %C, i32 %X, i32 %Y) { + %Cond = icmp ult i32 %X, %Y ; [#uses=1] + %X.upgrd.2 = select i1 %Cond, float %B, float %C ; [#uses=1] + ret float %X.upgrd.2 } -float %nofoldSel4(bool %A, float %B, float %C, int %X, int %Y) { - ; X86 doesn't have a cmov that reads the right flags for this! - %Cond = setlt int %X, %Y - %X = select bool %Cond, float %B, float %C - ret float %X +define float @nofoldSel4(i1 %A, float %B, float %C, i32 %X, i32 %Y) { + %Cond = icmp slt i32 %X, %Y ; [#uses=1] + %X.upgrd.3 = select i1 %Cond, float %B, float %C ; [#uses=1] + ret float %X.upgrd.3 } - From bruno.cardoso at gmail.com Mon Oct 8 21:55:32 2007 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Tue, 09 Oct 2007 02:55:32 -0000 Subject: [llvm-commits] [llvm] r42778 - in /llvm/trunk/lib/Target/Mips: MipsInstrFormats.td MipsInstrInfo.td Message-ID: <200710090255.l992tWax019304@zion.cs.uiuc.edu> Author: bruno Date: Mon Oct 8 21:55:31 2007 New Revision: 42778 URL: http://llvm.org/viewvc/llvm-project?rev=42778&view=rev Log: Position Independent Code (PIC) support [1] - Modified instruction format to handle pseudo instructions - Added LoadAddr SDNode to load symbols. Modified: llvm/trunk/lib/Target/Mips/MipsInstrFormats.td llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Modified: llvm/trunk/lib/Target/Mips/MipsInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrFormats.td?rev=42778&r1=42777&r2=42778&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrFormats.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrFormats.td Mon Oct 8 21:55:31 2007 @@ -42,6 +42,9 @@ let Itinerary = itin; } +// Mips Pseudo Instructions Format +class PseudoInstMips pattern>: + MipsInst; //===----------------------------------------------------------------------===// // Format R instruction class in Mips : <|opcode|rs|rt|rd|shamt|funct|> @@ -98,3 +101,4 @@ let Inst{25-0} = addr; } + Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=42778&r1=42777&r2=42778&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Mon Oct 8 21:55:31 2007 @@ -24,7 +24,7 @@ // Hi and Lo nodes are created to let easy manipulation of 16-bit when // handling 32-bit immediates. They are used on MipsISelLowering to -// lower stuff like GlobalAddress, ExternalSymbol, ... +// lower stuff like GlobalAddress, ExternalSymbol, ... on static model // This two nodes have nothing to do with Mips Registers Hi and Lo. def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp, [SDNPOutFlag]>; def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>; @@ -34,6 +34,9 @@ def MipsAdd : SDNode<"MipsISD::Add", SDTIntBinOp, [SDNPCommutative, SDNPAssociative, SDNPOptInFlag]>; +// Used to Load Addresses on PIC code. +def MipsLoadAddr: SDNode<"MipsISD::LoadAddr", SDTIntUnaryOp>; + // Return def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; def MipsRet : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain, @@ -46,12 +49,22 @@ def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeq, [SDNPHasChain, SDNPOutFlag]>; +//===----------------------------------------------------------------------===// +// Mips Instruction Predicate Definitions. +//===----------------------------------------------------------------------===// +def IsStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">; + +//===----------------------------------------------------------------------===// +// Mips Operand, Complex Patterns and Transformations Definitions. +//===----------------------------------------------------------------------===// + // Instruction operand types def brtarget : Operand; def calltarget : Operand; def uimm16 : Operand; def simm16 : Operand; def shamt : Operand; +def addrlabel : Operand; // Address operand def mem : Operand { @@ -59,10 +72,6 @@ let MIOperandInfo = (ops simm16, CPURegs); } -//===----------------------------------------------------------------------===// -// Mips Patterns and Transformations -//===----------------------------------------------------------------------===// - // Transformation Function - get the lower 16 bits. def LO16 : SDNodeXFormgetValue() & 0xFFFF); @@ -280,7 +289,7 @@ let isCall=1, hasDelaySlot=1, // All calls clobber the non-callee saved registers... Defs = [AT, V0, V1, A0, A1, A2, A3, T0, T1, T2, - T3, T4, T5, T6, T7, T8, T9, K0, K1, GP] in { + T3, T4, T5, T6, T7, T8, T9, K0, K1] in { class JumpLink op, string instr_asm>: FJ< op, (outs), @@ -343,22 +352,34 @@ // Pseudo instructions //===----------------------------------------------------------------------===// -class Pseudo pattern>: - MipsInst; - // As stack alignment is always done with addiu, we need a 16-bit immediate let Defs = [SP], Uses = [SP] in { -def ADJCALLSTACKDOWN : Pseudo<(outs), (ins uimm16:$amt), - "!ADJCALLSTACKDOWN $amt", - [(callseq_start imm:$amt)]>; -def ADJCALLSTACKUP : Pseudo<(outs), (ins uimm16:$amt), - "!ADJCALLSTACKUP $amt", - [(callseq_end imm:$amt)]>; +def ADJCALLSTACKDOWN : PseudoInstMips<(outs), (ins uimm16:$amt), + "!ADJCALLSTACKDOWN $amt", + [(callseq_start imm:$amt)]>; +def ADJCALLSTACKUP : PseudoInstMips<(outs), (ins uimm16:$amt), + "!ADJCALLSTACKUP $amt", + [(callseq_end imm:$amt)]>; } -def IMPLICIT_DEF_CPURegs : Pseudo<(outs CPURegs:$dst), (ins), - "!IMPLICIT_DEF $dst", - [(set CPURegs:$dst, (undef))]>; +def IMPLICIT_DEF_CPURegs : PseudoInstMips<(outs CPURegs:$dst), (ins), + "!IMPLICIT_DEF $dst", + [(set CPURegs:$dst, (undef))]>; + +// When handling PIC code the assembler needs .cpload and .cprestore +// directives. If the real instructions corresponding these directives +// are used, we have the same behavior, but get also a bunch of warnings +// from the assembler. +def CPLOAD: PseudoInstMips<(outs), (ins CPURegs:$reg), + ".set noreorder\n\t.cpload $reg\n\t.set reorder", []>; +def CPRESTORE: PseudoInstMips<(outs), (ins uimm16:$loc), + ".cprestore $loc", []>; + +// Used on PIC code only, it loads the address of label into register reg. The +// address is calculated from the global pointer ($gp) and is expanded by the +// assembler into two instructions "lw" and "addiu". +def LA: PseudoInstMips<(outs CPURegs:$dst), (ins addrlabel:$label), + "la $dst, $label", []>; //===----------------------------------------------------------------------===// // Instruction definition @@ -507,6 +528,7 @@ def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>; def : Pat<(MipsAdd CPURegs:$hi, (MipsLo tglobaladdr:$lo)), (ADDiu CPURegs:$hi, tglobaladdr:$lo)>; +def : Pat<(MipsLoadAddr tglobaladdr:$in), (LA tglobaladdr:$in)>; // Mips does not have not, so we increase the operation def : Pat<(not CPURegs:$in), From bruno.cardoso at gmail.com Mon Oct 8 22:01:20 2007 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Tue, 09 Oct 2007 03:01:20 -0000 Subject: [llvm-commits] [llvm] r42779 - in /llvm/trunk/lib/Target/Mips: MipsAsmPrinter.cpp MipsMachineFunction.h MipsTargetMachine.cpp Message-ID: <200710090301.l9931K06019503@zion.cs.uiuc.edu> Author: bruno Date: Mon Oct 8 22:01:19 2007 New Revision: 42779 URL: http://llvm.org/viewvc/llvm-project?rev=42779&view=rev Log: Position Independent Code (PIC) support [2] - Added a function to hold the stack location where GP must be stored during LowerCALL - AsmPrinter now emits directives based on relocation type - PIC_ set to default relocation type (same as GCC) Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp llvm/trunk/lib/Target/Mips/MipsMachineFunction.h llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=42779&r1=42778&r2=42779&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Mon Oct 8 22:01:19 2007 @@ -67,7 +67,7 @@ void printHex32(unsigned int Value); void emitFunctionStart(MachineFunction &MF); - void emitFunctionEnd(); + void emitFunctionEnd(MachineFunction &MF); void emitFrameDirective(MachineFunction &MF); void emitMaskDirective(MachineFunction &MF); void emitFMaskDirective(MachineFunction &MF); @@ -209,10 +209,12 @@ Bitmask |= (1 << MipsRegisterInfo::getRegisterNumbering(CSI[i].getReg())); if (RI.hasFP(MF)) - Bitmask |= (1 << MipsRegisterInfo::getRegisterNumbering(RI.getFrameRegister(MF))); + Bitmask |= (1 << MipsRegisterInfo:: + getRegisterNumbering(RI.getFrameRegister(MF))); if (MF.getFrameInfo()->hasCalls()) - Bitmask |= (1 << MipsRegisterInfo::getRegisterNumbering(RI.getRARegister())); + Bitmask |= (1 << MipsRegisterInfo:: + getRegisterNumbering(RI.getRARegister())); return Bitmask; } @@ -247,16 +249,24 @@ emitFrameDirective(MF); emitMaskDirective(MF); emitFMaskDirective(MF); - emitSetDirective(NOREORDER); - emitSetDirective(NOMACRO); + + if (MF.getTarget().getRelocationModel() == Reloc::Static) { + emitSetDirective(NOREORDER); + emitSetDirective(NOMACRO); + } + O << "\n"; } /// Emit the directives used by GAS on the end of functions void MipsAsmPrinter:: -emitFunctionEnd() { - emitSetDirective(MACRO); - emitSetDirective(REORDER); +emitFunctionEnd(MachineFunction &MF) +{ + if (MF.getTarget().getRelocationModel() == Reloc::Static) { + emitSetDirective(MACRO); + emitSetDirective(REORDER); + } + O << "\t.end\t" << CurrentFnName << "\n"; } @@ -298,7 +308,7 @@ } // Emit function end directives - emitFunctionEnd(); + emitFunctionEnd(MF); // We didn't modify anything. return false; Modified: llvm/trunk/lib/Target/Mips/MipsMachineFunction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsMachineFunction.h?rev=42779&r1=42778&r2=42779&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsMachineFunction.h (original) +++ llvm/trunk/lib/Target/Mips/MipsMachineFunction.h Mon Oct 8 22:01:19 2007 @@ -33,6 +33,11 @@ /// the Return Address must be saved int RAStackOffset; + /// When PIC is used the GP must be saved on the stack + /// on the function prologue, so a reference to its stack + /// location must be kept. + int GPStackOffset; + /// MipsFIHolder - Holds a FrameIndex and it's Stack Pointer Offset struct MipsFIHolder { @@ -69,6 +74,9 @@ int getRAStackOffset() const { return RAStackOffset; } void setRAStackOffset(int Off) { RAStackOffset = Off; } + int getGPStackOffset() const { return GPStackOffset; } + void setGPStackOffset(int Off) { GPStackOffset = Off; } + int getTopSavedRegOffset() const { return (RAStackOffset > FPStackOffset) ? (RAStackOffset) : (FPStackOffset); Modified: llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp?rev=42779&r1=42778&r2=42779&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp Mon Oct 8 22:01:19 2007 @@ -39,7 +39,11 @@ MipsTargetMachine(const Module &M, const std::string &FS): Subtarget(*this, M, FS), DataLayout("E-p:32:32:32"), InstrInfo(*this), FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0), - TLInfo(*this) {} + TLInfo(*this) +{ + if (getRelocationModel() != Reloc::Static) + setRelocationModel(Reloc::PIC_); +} // return 0 and must specify -march to gen MIPS code. unsigned MipsTargetMachine:: From bruno.cardoso at gmail.com Mon Oct 8 22:15:13 2007 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Tue, 09 Oct 2007 03:15:13 -0000 Subject: [llvm-commits] [llvm] r42780 - in /llvm/trunk/lib/Target/Mips: MipsISelLowering.cpp MipsISelLowering.h MipsRegisterInfo.cpp Message-ID: <200710090315.l993FExC020020@zion.cs.uiuc.edu> Author: bruno Date: Mon Oct 8 22:15:11 2007 New Revision: 42780 URL: http://llvm.org/viewvc/llvm-project?rev=42780&view=rev Log: Position Independent Code (PIC) support [3] Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.h llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=42780&r1=42779&r2=42780&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Mon Oct 8 22:15:11 2007 @@ -44,6 +44,7 @@ case MipsISD::Lo : return "MipsISD::Lo"; case MipsISD::Ret : return "MipsISD::Ret"; case MipsISD::Add : return "MipsISD::Add"; + case MipsISD::LoadAddr : return "MipsISD::LoadAddr"; default : return NULL; } } @@ -146,18 +147,25 @@ SDOperand MipsTargetLowering:: LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) { + SDOperand ResNode; GlobalValue *GV = cast(Op)->getGlobal(); SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32); - const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::i32, MVT::Flag); - SDOperand Ops[] = { GA }; + // On PIC code global addresses are loaded with "la" instruction + if (!(getTargetMachine().getRelocationModel() == Reloc::PIC_)) { + const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::i32, MVT::Flag); + SDOperand Ops[] = { GA }; + + SDOperand Hi = DAG.getNode(MipsISD::Hi, VTs, 2, Ops, 1); + SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, GA); + + SDOperand InFlag = Hi.getValue(1); + ResNode = DAG.getNode(MipsISD::Add, MVT::i32, Lo, Hi, InFlag); + } else + ResNode = DAG.getNode(MipsISD::LoadAddr, MVT::i32, GA); - SDOperand Hi = DAG.getNode(MipsISD::Hi, VTs, 2, Ops, 1); - SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, GA); - - SDOperand InFlag = Hi.getValue(1); - return DAG.getNode(MipsISD::Add, MVT::i32, Lo, Hi, InFlag); + return ResNode; } SDOperand MipsTargetLowering:: @@ -236,6 +244,7 @@ SmallVector MemOpChains; SDOperand StackPtr; + unsigned LastStackLoc=0; // Walk the register/memloc assignments, inserting copies/loads. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { @@ -273,8 +282,9 @@ // Create the frame index object for this incoming parameter // This guarantees that when allocating Local Area the firsts // 16 bytes which are alwayes reserved won't be overwritten. + LastStackLoc = (16 + VA.getLocMemOffset()); int FI = MFI->CreateFixedObject(MVT::getSizeInBits(VA.getValVT())/8, - (16 + VA.getLocMemOffset())); + LastStackLoc); SDOperand PtrOff = DAG.getFrameIndex(FI,getPointerTy()); @@ -284,6 +294,14 @@ } } + // Create a stack location to hold GP when PIC is used + if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { + LastStackLoc = (!LastStackLoc) ? (16) : (LastStackLoc+4); + MipsFunctionInfo *MipsFI = MF.getInfo(); + MFI->CreateFixedObject(4, LastStackLoc); + MipsFI->setGPStackOffset(LastStackLoc); + } + // Transform all store nodes into one single node because // all store nodes are independent of each other. if (!MemOpChains.empty()) @@ -301,13 +319,13 @@ InFlag = Chain.getValue(1); } - // If the callee is a GlobalAddress node (quite common, every direct - // call is) turn it into a TargetGlobalAddress node so that legalize - // doesn't hack it. - if (GlobalAddressSDNode *G = dyn_cast(Callee)) { + // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every + // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol + // node so that legalize doesn't hack it. Otherwise we have an indirect call, + // if PIC is used, the call must use register GP + if (GlobalAddressSDNode *G = dyn_cast(Callee)) Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy()); - } else - if (ExternalSymbolSDNode *S = dyn_cast(Callee)) + else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy()); // MipsJmpLink = #chain, #target_address, #opt_in_flags... @@ -543,8 +561,7 @@ // ISD::RET => ret chain, (regnum1,val1), ... // So i*2+1 index only the regnums - Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), - Op.getOperand(i*2+1), Flag); + Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag); // guarantee that all emitted copies are // stuck together, avoiding something bad @@ -554,10 +571,10 @@ // Return on Mips is always a "jr $ra" if (Flag.Val) return DAG.getNode(MipsISD::Ret, MVT::Other, - Chain, DAG.getRegister(Mips::RA, MVT::i32), Flag); + Chain, DAG.getRegister(Mips::RA, MVT::i32), Flag); else // Return Void return DAG.getNode(MipsISD::Ret, MVT::Other, - Chain, DAG.getRegister(Mips::RA, MVT::i32)); + Chain, DAG.getRegister(Mips::RA, MVT::i32)); } //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=42780&r1=42779&r2=42780&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Mon Oct 8 22:15:11 2007 @@ -41,7 +41,10 @@ Ret, // Need to support addition with a input flag - Add + Add, + + // Used on PIC Code to load global addresses + LoadAddr }; } Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp?rev=42780&r1=42779&r2=42780&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp Mon Oct 8 22:15:11 2007 @@ -369,9 +369,10 @@ MachineFrameInfo *MFI = MF.getFrameInfo(); MipsFunctionInfo *MipsFI = MF.getInfo(); MachineBasicBlock::iterator MBBI = MBB.begin(); + bool isPIC = (MF.getTarget().getRelocationModel() == Reloc::PIC_); - // Replace the dummy '0' SPOffset by the negative offsets, as - // explained on LowerFORMAL_ARGUMENTS + // Replace the dummy '0' SPOffset by the negative + // offsets, as explained on LowerFORMAL_ARGUMENTS MipsFI->adjustLoadArgsFI(MFI); MipsFI->adjustStoreVarArgsFI(MFI); @@ -421,6 +422,10 @@ // Update frame info MFI->setStackSize(NumBytes); + // PIC speficic function prologue + if (isPIC) + BuildMI(MBB, MBBI, TII.get(Mips::CPLOAD)).addReg(Mips::T9); + // Adjust stack : addi sp, sp, (-imm) BuildMI(MBB, MBBI, TII.get(Mips::ADDiu), Mips::SP) .addReg(Mips::SP).addImm(-NumBytes); @@ -443,6 +448,12 @@ BuildMI(MBB, MBBI, TII.get(Mips::ADDu), Mips::FP) .addReg(Mips::SP).addReg(Mips::ZERO); } + + // PIC speficic function prologue + if ((isPIC) && (MFI->hasCalls())) + BuildMI(MBB, MBBI, TII.get(Mips::CPRESTORE)) + .addImm(MipsFI->getGPStackOffset()); + } void MipsRegisterInfo:: From sabre at nondot.org Mon Oct 8 22:40:32 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 09 Oct 2007 03:40:32 -0000 Subject: [llvm-commits] [llvm] r42781 - in /llvm/trunk: include/llvm/ADT/FoldingSet.h lib/Support/FoldingSet.cpp Message-ID: <200710090340.l993eW9x020743@zion.cs.uiuc.edu> Author: lattner Date: Mon Oct 8 22:40:30 2007 New Revision: 42781 URL: http://llvm.org/viewvc/llvm-project?rev=42781&view=rev Log: Change a #include into a forward declaration Modified: llvm/trunk/include/llvm/ADT/FoldingSet.h llvm/trunk/lib/Support/FoldingSet.cpp Modified: llvm/trunk/include/llvm/ADT/FoldingSet.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/FoldingSet.h?rev=42781&r1=42780&r2=42781&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/FoldingSet.h (original) +++ llvm/trunk/include/llvm/ADT/FoldingSet.h Mon Oct 8 22:40:30 2007 @@ -18,10 +18,10 @@ #include "llvm/Support/DataTypes.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/APFloat.h" #include namespace llvm { + class APFloat; /// This folding set used for two purposes: /// 1. Given information about a node we want to create, look up the unique Modified: llvm/trunk/lib/Support/FoldingSet.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/FoldingSet.cpp?rev=42781&r1=42780&r2=42781&view=diff ============================================================================== --- llvm/trunk/lib/Support/FoldingSet.cpp (original) +++ llvm/trunk/lib/Support/FoldingSet.cpp Mon Oct 8 22:40:30 2007 @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/APFloat.h" #include "llvm/Support/MathExtras.h" #include using namespace llvm; From sabre at nondot.org Tue Oct 9 00:42:14 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 09 Oct 2007 05:42:14 -0000 Subject: [llvm-commits] [llvm] r42782 - /llvm/trunk/include/llvm/ADT/DenseMap.h Message-ID: <200710090542.l995gF8A024993@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 9 00:42:12 2007 New Revision: 42782 URL: http://llvm.org/viewvc/llvm-project?rev=42782&view=rev Log: Fix problems where DenseMap used operator!= instead of correctly calling the traits implementation of isEqual. Modified: llvm/trunk/include/llvm/ADT/DenseMap.h Modified: llvm/trunk/include/llvm/ADT/DenseMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=42782&r1=42781&r2=42782&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/DenseMap.h (original) +++ llvm/trunk/include/llvm/ADT/DenseMap.h Tue Oct 9 00:42:12 2007 @@ -75,7 +75,8 @@ ~DenseMap() { const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) { - if (P->first != EmptyKey && P->first != TombstoneKey) + if (!KeyInfoT::isEqual(P->first, EmptyKey) && + !KeyInfoT::isEqual(P->first, TombstoneKey)) P->second.~ValueT(); P->first.~KeyT(); } @@ -113,8 +114,8 @@ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) { - if (P->first != EmptyKey) { - if (P->first != TombstoneKey) { + if (!KeyInfoT::isEqual(P->first, EmptyKey)) { + if (!KeyInfoT::isEqual(P->first, TombstoneKey)) { P->second.~ValueT(); --NumEntries; } @@ -192,7 +193,8 @@ if (NumBuckets != 0 && (!KeyInfoT::isPod() || !ValueInfoT::isPod())) { const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) { - if (P->first != EmptyKey && P->first != TombstoneKey) + if (!KeyInfoT::isEqual(P->first, EmptyKey) && + !KeyInfoT::isEqual(P->first, TombstoneKey)) P->second.~ValueT(); P->first.~KeyT(); } @@ -211,8 +213,8 @@ else for (size_t i = 0; i < other.NumBuckets; ++i) { new (Buckets[i].first) KeyT(other.Buckets[i].first); - if (Buckets[i].first != getEmptyKey() && - Buckets[i].first != getTombstoneKey()) + if (!KeyInfoT::isEqual(Buckets[i].first, getEmptyKey()) && + !KeyInfoT::isEqual(Buckets[i].first, getTombstoneKey())) new (&Buckets[i].second) ValueT(other.Buckets[i].second); } NumBuckets = other.NumBuckets; @@ -237,7 +239,7 @@ ++NumEntries; // If we are writing over a tombstone, remember this. - if (TheBucket->first != getEmptyKey()) + if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey())) --NumTombstones; TheBucket->first = Key; @@ -268,7 +270,8 @@ BucketT *FoundTombstone = 0; const KeyT EmptyKey = getEmptyKey(); const KeyT TombstoneKey = getTombstoneKey(); - assert(Val != EmptyKey && Val != TombstoneKey && + assert(!KeyInfoT::isEqual(Val, EmptyKey) && + !KeyInfoT::isEqual(Val, TombstoneKey) && "Empty/Tombstone value shouldn't be inserted into map!"); while (1) { @@ -331,7 +334,8 @@ // Insert all the old elements. const KeyT TombstoneKey = getTombstoneKey(); for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) { - if (B->first != EmptyKey && B->first != TombstoneKey) { + if (!KeyInfoT::isEqual(B->first, EmptyKey) && + !KeyInfoT::isEqual(B->first, TombstoneKey)) { // Insert the key/value into the new table. BucketT *DestBucket; bool FoundVal = LookupBucketFor(B->first, DestBucket); @@ -368,7 +372,8 @@ // Free the old buckets. const KeyT TombstoneKey = getTombstoneKey(); for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) { - if (B->first != EmptyKey && B->first != TombstoneKey) { + if (!KeyInfoT::isEqual(B->first, EmptyKey) && + !KeyInfoT::isEqual(B->first, TombstoneKey)) { // Free the value. B->second.~ValueT(); } From clattner at apple.com Tue Oct 9 01:06:52 2007 From: clattner at apple.com (Chris Lattner) Date: Mon, 8 Oct 2007 23:06:52 -0700 Subject: [llvm-commits] [llvm] r42765 - in /llvm/trunk/test/CodeGen/X86: mul128.ll mul64.ll In-Reply-To: <200710082048.l98KmDlB006656@zion.cs.uiuc.edu> References: <200710082048.l98KmDlB006656@zion.cs.uiuc.edu> Message-ID: <819FD3B8-1FCA-482D-973E-4675C2F09448@apple.com> On Oct 8, 2007, at 1:48 PM, Dan Gohman wrote: > Author: djg > Date: Mon Oct 8 15:48:12 2007 > New Revision: 42765 > > URL: http://llvm.org/viewvc/llvm-project?rev=42765&view=rev > Log: > These two tests now require only three multiply instructions, > instead of four. Very nice Dan! I think this completes the "Add a MUL2U and MUL2S nodes to represent a multiply that returns both the.." note in X86/ README.txt. Among other nice things, we now compile: long long test(int X, int Y) { return (long long)X*Y; } into: _test: movl 4(%esp), %ecx movl 8(%esp), %eax imull %ecx ret instead of: _test: pushl %esi movl 8(%esp), %ecx movl 12(%esp), %esi movl %esi, %eax imull %ecx imull %ecx, %esi movl %esi, %eax popl %esi ret Can you please update the readme and add regtests for the cases it mentions? Thanks for tackling this! -Chris From evan.cheng at apple.com Tue Oct 9 02:14:53 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 09 Oct 2007 07:14:53 -0000 Subject: [llvm-commits] [llvm] r42783 - /llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200710090714.l997ErFL029546@zion.cs.uiuc.edu> Author: evancheng Date: Tue Oct 9 02:14:53 2007 New Revision: 42783 URL: http://llvm.org/viewvc/llvm-project?rev=42783&view=rev Log: Under 64-bit mode use LEA64_32r instead of LEA64r to save a byte. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=42783&r1=42782&r2=42783&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Tue Oct 9 02:14:53 2007 @@ -271,12 +271,14 @@ if (hasLiveCondCodeDef(MI)) return 0; + bool is64Bit = TM.getSubtarget().is64Bit(); switch (MIOpc) { default: return 0; case X86::INC64r: case X86::INC32r: { assert(MI->getNumOperands() >= 2 && "Unknown inc instruction!"); - unsigned Opc = MIOpc == X86::INC64r ? X86::LEA64r : X86::LEA32r; + unsigned Opc = MIOpc == X86::INC64r ? X86::LEA64r + : (is64Bit ? X86::LEA64_32r : X86::LEA32r); NewMI = addRegOffset(BuildMI(get(Opc), Dest), Src, 1); break; } @@ -289,7 +291,8 @@ case X86::DEC64r: case X86::DEC32r: { assert(MI->getNumOperands() >= 2 && "Unknown dec instruction!"); - unsigned Opc = MIOpc == X86::DEC64r ? X86::LEA64r : X86::LEA32r; + unsigned Opc = MIOpc == X86::DEC64r ? X86::LEA64r + : (is64Bit ? X86::LEA64_32r : X86::LEA32r); NewMI = addRegOffset(BuildMI(get(Opc), Dest), Src, -1); break; } @@ -302,7 +305,8 @@ case X86::ADD64rr: case X86::ADD32rr: { assert(MI->getNumOperands() >= 3 && "Unknown add instruction!"); - unsigned Opc = MIOpc == X86::ADD64rr ? X86::LEA64r : X86::LEA32r; + unsigned Opc = MIOpc == X86::ADD64rr ? X86::LEA64r + : (is64Bit ? X86::LEA64_32r : X86::LEA32r); NewMI = addRegReg(BuildMI(get(Opc), Dest), Src, MI->getOperand(2).getReg()); break; @@ -323,9 +327,11 @@ case X86::ADD32ri: case X86::ADD32ri8: assert(MI->getNumOperands() >= 3 && "Unknown add instruction!"); - if (MI->getOperand(2).isImmediate()) - NewMI = addRegOffset(BuildMI(get(X86::LEA32r), Dest), Src, + if (MI->getOperand(2).isImmediate()) { + unsigned Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r; + NewMI = addRegOffset(BuildMI(get(Opc), Dest), Src, MI->getOperand(2).getImmedValue()); + } break; case X86::ADD16ri: case X86::ADD16ri8: @@ -347,7 +353,8 @@ AM.Scale = 1 << ShAmt; AM.IndexReg = Src; unsigned Opc = MIOpc == X86::SHL64ri ? X86::LEA64r - : (MIOpc == X86::SHL32ri ? X86::LEA32r : X86::LEA16r); + : (MIOpc == X86::SHL32ri + ? (is64Bit ? X86::LEA64_32r : X86::LEA32r) : X86::LEA16r); NewMI = addFullAddress(BuildMI(get(Opc), Dest), AM); } break; From djg at cray.com Tue Oct 9 10:39:38 2007 From: djg at cray.com (Dan Gohman) Date: Tue, 09 Oct 2007 15:39:38 -0000 Subject: [llvm-commits] [llvm] r42784 - in /llvm/trunk/test/CodeGen/X86: extmul128.ll extmul64.ll Message-ID: <200710091539.l99FdcD8025388@zion.cs.uiuc.edu> Author: djg Date: Tue Oct 9 10:39:37 2007 New Revision: 42784 URL: http://llvm.org/viewvc/llvm-project?rev=42784&view=rev Log: These two tests now require only two multiply instructions, instead of four. Added: llvm/trunk/test/CodeGen/X86/extmul128.ll llvm/trunk/test/CodeGen/X86/extmul64.ll Added: llvm/trunk/test/CodeGen/X86/extmul128.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/extmul128.ll?rev=42784&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/extmul128.ll (added) +++ llvm/trunk/test/CodeGen/X86/extmul128.ll Tue Oct 9 10:39:37 2007 @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | grep mul | count 2 + +define i128 @i64_sext_i128(i64 %a, i64 %b) { + %aa = sext i64 %a to i128 + %bb = sext i64 %b to i128 + %cc = mul i128 %aa, %bb + ret i128 %cc +} +define i128 @i64_zext_i128(i64 %a, i64 %b) { + %aa = zext i64 %a to i128 + %bb = zext i64 %b to i128 + %cc = mul i128 %aa, %bb + ret i128 %cc +} Added: llvm/trunk/test/CodeGen/X86/extmul64.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/extmul64.ll?rev=42784&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/extmul64.ll (added) +++ llvm/trunk/test/CodeGen/X86/extmul64.ll Tue Oct 9 10:39:37 2007 @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep mul | count 2 + +define i64 @i32_sext_i64(i32 %a, i32 %b) { + %aa = sext i32 %a to i64 + %bb = sext i32 %b to i64 + %cc = mul i64 %aa, %bb + ret i64 %cc +} +define i64 @i32_zext_i64(i32 %a, i32 %b) { + %aa = zext i32 %a to i64 + %bb = zext i32 %b to i64 + %cc = mul i64 %aa, %bb + ret i64 %cc +} From djg at cray.com Tue Oct 9 10:42:21 2007 From: djg at cray.com (Dan Gohman) Date: Tue, 09 Oct 2007 15:42:21 -0000 Subject: [llvm-commits] [llvm] r42785 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200710091542.l99FgLmH025479@zion.cs.uiuc.edu> Author: djg Date: Tue Oct 9 10:42:21 2007 New Revision: 42785 URL: http://llvm.org/viewvc/llvm-project?rev=42785&view=rev Log: This is done. Modified: llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=42785&r1=42784&r2=42785&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Tue Oct 9 10:42:21 2007 @@ -10,36 +10,6 @@ //===---------------------------------------------------------------------===// -Add a MUL2U and MUL2S nodes to represent a multiply that returns both the -Hi and Lo parts (combination of MUL and MULH[SU] into one node). Add this to -X86, & make the dag combiner produce it when needed. This will eliminate one -imul from the code generated for: - -long long test(long long X, long long Y) { return X*Y; } - -by using the EAX result from the mul. We should add a similar node for -DIVREM. - -another case is: - -long long test(int X, int Y) { return (long long)X*Y; } - -... which should only be one imul instruction. - -or: - -unsigned long long int t2(unsigned int a, unsigned int b) { - return (unsigned long long)a * b; -} - -... which should be one mul instruction. - - -This can be done with a custom expander, but it would be nice to move this to -generic code. - -//===---------------------------------------------------------------------===// - CodeGen/X86/lea-3.ll:test3 should be a single LEA, not a shift/move. The X86 backend knows how to three-addressify this shift, but it appears the register allocator isn't even asking it to do so in this case. We should investigate From djg at cray.com Tue Oct 9 10:44:37 2007 From: djg at cray.com (Dan Gohman) Date: Tue, 09 Oct 2007 15:44:37 -0000 Subject: [llvm-commits] [llvm] r42786 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200710091544.l99Fib6Z025559@zion.cs.uiuc.edu> Author: djg Date: Tue Oct 9 10:44:37 2007 New Revision: 42786 URL: http://llvm.org/viewvc/llvm-project?rev=42786&view=rev Log: Fix grammar in a comment. Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=42786&r1=42785&r2=42786&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Oct 9 10:44:37 2007 @@ -1090,9 +1090,9 @@ SDOperand N0 = Node->getOperand(0); SDOperand N1 = Node->getOperand(1); - // There are several forms of IMUL just return the low part and don't - // have fixed-register operands. If we don't need the high part, use - // these instead. They can be selected with the generated ISel code. + // There are several forms of IMUL that just return the low part and + // don't have fixed-register operands. If we don't need the high part, + // use these instead. They can be selected with the generated ISel code. if (NVT != MVT::i8 && N.getValue(1).use_empty()) { N = CurDAG->getNode(ISD::MUL, NVT, N0, N1); From djg at cray.com Tue Oct 9 10:45:13 2007 From: djg at cray.com (Dan Gohman) Date: Tue, 09 Oct 2007 15:45:13 -0000 Subject: [llvm-commits] [llvm] r42787 - /llvm/trunk/lib/Target/X86/X86ISelLowering.h Message-ID: <200710091545.l99FjDLQ025584@zion.cs.uiuc.edu> Author: djg Date: Tue Oct 9 10:45:13 2007 New Revision: 42787 URL: http://llvm.org/viewvc/llvm-project?rev=42787&view=rev Log: LowerIntegerDivOrRem no longer exists. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=42787&r1=42786&r2=42787&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Tue Oct 9 10:45:13 2007 @@ -416,7 +416,6 @@ SDOperand LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG); SDOperand LowerExternalSymbol(SDOperand Op, SelectionDAG &DAG); SDOperand LowerShift(SDOperand Op, SelectionDAG &DAG); - SDOperand LowerIntegerDivOrRem(SDOperand Op, SelectionDAG &DAG); SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG); SDOperand LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG); SDOperand LowerFABS(SDOperand Op, SelectionDAG &DAG); From djg at cray.com Tue Oct 9 11:04:58 2007 From: djg at cray.com (Dan Gohman) Date: Tue, 09 Oct 2007 16:04:58 -0000 Subject: [llvm-commits] [llvm] r42788 - in /llvm/trunk: include/llvm/Support/CommandLine.h lib/Support/CommandLine.cpp Message-ID: <200710091604.l99G4wfg026262@zion.cs.uiuc.edu> Author: djg Date: Tue Oct 9 11:04:57 2007 New Revision: 42788 URL: http://llvm.org/viewvc/llvm-project?rev=42788&view=rev Log: Pass argc by value, not by reference, since it isn't modified. Modified: llvm/trunk/include/llvm/Support/CommandLine.h llvm/trunk/lib/Support/CommandLine.cpp Modified: llvm/trunk/include/llvm/Support/CommandLine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CommandLine.h?rev=42788&r1=42787&r2=42788&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CommandLine.h (original) +++ llvm/trunk/include/llvm/Support/CommandLine.h Tue Oct 9 11:04:57 2007 @@ -40,7 +40,7 @@ //===----------------------------------------------------------------------===// // ParseCommandLineOptions - Command line option processing entry point. // -void ParseCommandLineOptions(int &argc, char **argv, +void ParseCommandLineOptions(int argc, char **argv, const char *Overview = 0); //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Support/CommandLine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CommandLine.cpp?rev=42788&r1=42787&r2=42788&view=diff ============================================================================== --- llvm/trunk/lib/Support/CommandLine.cpp (original) +++ llvm/trunk/lib/Support/CommandLine.cpp Tue Oct 9 11:04:57 2007 @@ -332,7 +332,7 @@ free (*i); } -void cl::ParseCommandLineOptions(int &argc, char **argv, +void cl::ParseCommandLineOptions(int argc, char **argv, const char *Overview) { // Process all registered options. std::vector PositionalOpts; From sabre at nondot.org Tue Oct 9 11:27:45 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 09 Oct 2007 16:27:45 -0000 Subject: [llvm-commits] [llvm] r42789 - /llvm/trunk/include/llvm/Support/CommandLine.h Message-ID: <200710091627.l99GRjFS027038@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 9 11:27:44 2007 New Revision: 42789 URL: http://llvm.org/viewvc/llvm-project?rev=42789&view=rev Log: update prototype, fixing build error Modified: llvm/trunk/include/llvm/Support/CommandLine.h Modified: llvm/trunk/include/llvm/Support/CommandLine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CommandLine.h?rev=42789&r1=42788&r2=42789&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CommandLine.h (original) +++ llvm/trunk/include/llvm/Support/CommandLine.h Tue Oct 9 11:27:44 2007 @@ -133,7 +133,7 @@ // class alias; class Option { - friend void cl::ParseCommandLineOptions(int &, char **, const char *); + friend void cl::ParseCommandLineOptions(int, char **, const char *); friend class alias; // handleOccurrences - Overriden by subclasses to handle the value passed into From djg at cray.com Tue Oct 9 13:39:49 2007 From: djg at cray.com (Dan Gohman) Date: Tue, 09 Oct 2007 18:39:49 -0000 Subject: [llvm-commits] [llvm] r42805 - /llvm/trunk/include/llvm/Support/CommandLine.h Message-ID: <200710091839.l99IdnQA000314@zion.cs.uiuc.edu> Author: djg Date: Tue Oct 9 13:39:48 2007 New Revision: 42805 URL: http://llvm.org/viewvc/llvm-project?rev=42805&view=rev Log: Remove an unnecessary friend declaration. Modified: llvm/trunk/include/llvm/Support/CommandLine.h Modified: llvm/trunk/include/llvm/Support/CommandLine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CommandLine.h?rev=42805&r1=42804&r2=42805&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CommandLine.h (original) +++ llvm/trunk/include/llvm/Support/CommandLine.h Tue Oct 9 13:39:48 2007 @@ -133,7 +133,6 @@ // class alias; class Option { - friend void cl::ParseCommandLineOptions(int, char **, const char *); friend class alias; // handleOccurrences - Overriden by subclasses to handle the value passed into From dpatel at apple.com Tue Oct 9 14:49:19 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 09 Oct 2007 19:49:19 -0000 Subject: [llvm-commits] [llvm] r42806 - /llvm/trunk/include/llvm/Support/LLVMBuilder.h Message-ID: <200710091949.l99JnJZ1002769@zion.cs.uiuc.edu> Author: dpatel Date: Tue Oct 9 14:49:19 2007 New Revision: 42806 URL: http://llvm.org/viewvc/llvm-project?rev=42806&view=rev Log: Add LLVMFoldingBuilder Modified: llvm/trunk/include/llvm/Support/LLVMBuilder.h Modified: llvm/trunk/include/llvm/Support/LLVMBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/LLVMBuilder.h?rev=42806&r1=42805&r2=42806&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/LLVMBuilder.h (original) +++ llvm/trunk/include/llvm/Support/LLVMBuilder.h Tue Oct 9 14:49:19 2007 @@ -17,6 +17,7 @@ #include "llvm/BasicBlock.h" #include "llvm/Instructions.h" +#include "llvm/Constants.h" namespace llvm { @@ -416,9 +417,220 @@ } }; -// TODO: A version of LLVMBuilder that constant folds operands as they come in. -//class LLVMFoldingBuilder { -//}; +/// LLVMFoldingBuilder - A version of LLVMBuilder that constant folds operands +/// as they come in. +class LLVMFoldingBuilder : public LLVMBuilder { + +public: + LLVMFoldingBuilder() {} + explicit LLVMFoldingBuilder(BasicBlock *TheBB) + : LLVMBuilder(TheBB) {} + LLVMFoldingBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) + : LLVMBuilder(TheBB, IP) {} + + //===--------------------------------------------------------------------===// + // Instruction creation methods: Binary Operators + //===--------------------------------------------------------------------===// + + Value *CreateAdd(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getAdd(LC, RC); + return LLVMBuilder::CreateAdd(LHS, RHS, Name); + } + + Value *CreateSub(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getSub(LC, RC); + return LLVMBuilder::CreateSub(LHS, RHS, Name); + } + + Value *CreateMul(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getMul(LC, RC); + return LLVMBuilder::CreateMul(LHS, RHS, Name); + } + + Value *CreateUDiv(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getUDiv(LC, RC); + return LLVMBuilder::CreateUDiv(LHS, RHS, Name); + } + + Value *CreateSDiv(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getSDiv(LC, RC); + return LLVMBuilder::CreateSDiv(LHS, RHS, Name); + } + + Value *CreateFDiv(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getFDiv(LC, RC); + return LLVMBuilder::CreateFDiv(LHS, RHS, Name); + } + + Value *CreateURem(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getURem(LC, RC); + return LLVMBuilder::CreateURem(LHS, RHS, Name); + } + + Value *CreateSRem(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getSRem(LC, RC); + return LLVMBuilder::CreateSRem(LHS, RHS, Name); + } + + Value *CreateFRem(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getFRem(LC, RC); + return LLVMBuilder::CreateFRem(LHS, RHS, Name); + } + + Value *CreateAnd(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getAnd(LC, RC); + return LLVMBuilder::CreateAnd(LHS, RHS, Name); + } + + Value *CreateOr(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getOr(LC, RC); + return LLVMBuilder::CreateOr(LHS, RHS, Name); + } + + Value *CreateXor(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getXor(LC, RC); + return LLVMBuilder::CreateXor(LHS, RHS, Name); + } + + Value *CreateShl(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getShl(LC, RC); + return LLVMBuilder::CreateShl(LHS, RHS, Name); + } + + Value *CreateLShr(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getLShr(LC, RC); + return LLVMBuilder::CreateLShr(LHS, RHS, Name); + } + + Value *CreateAShr(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getAShr(LC, RC); + return LLVMBuilder::CreateAShr(LHS, RHS, Name); + } + + //===--------------------------------------------------------------------===// + // Instruction creation methods: Compare Instructions + //===--------------------------------------------------------------------===// + + Value *CreateICmpEQ(Value *LHS, Value *RHS, const char *Name = "") { + return CreateICmp(ICmpInst::ICMP_EQ, LHS, RHS, Name); + } + Value *CreateICmpNE(Value *LHS, Value *RHS, const char *Name = "") { + return CreateICmp(ICmpInst::ICMP_NE, LHS, RHS, Name); + } + Value *CreateICmpUGT(Value *LHS, Value *RHS, const char *Name = "") { + return CreateICmp(ICmpInst::ICMP_UGT, LHS, RHS, Name); + } + Value *CreateICmpUGE(Value *LHS, Value *RHS, const char *Name = "") { + return CreateICmp(ICmpInst::ICMP_UGE, LHS, RHS, Name); + } + Value *CreateICmpULT(Value *LHS, Value *RHS, const char *Name = "") { + return CreateICmp(ICmpInst::ICMP_ULT, LHS, RHS, Name); + } + Value *CreateICmpULE(Value *LHS, Value *RHS, const char *Name = "") { + return CreateICmp(ICmpInst::ICMP_ULE, LHS, RHS, Name); + } + Value *CreateICmpSGT(Value *LHS, Value *RHS, const char *Name = "") { + return CreateICmp(ICmpInst::ICMP_SGT, LHS, RHS, Name); + } + Value *CreateICmpSGE(Value *LHS, Value *RHS, const char *Name = "") { + return CreateICmp(ICmpInst::ICMP_SGE, LHS, RHS, Name); + } + Value *CreateICmpSLT(Value *LHS, Value *RHS, const char *Name = "") { + return CreateICmp(ICmpInst::ICMP_SLT, LHS, RHS, Name); + } + Value *CreateICmpSLE(Value *LHS, Value *RHS, const char *Name = "") { + return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name); + } + + Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name); + } + Value *CreateFCmpOGT(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name); + } + Value *CreateFCmpOGE(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name); + } + Value *CreateFCmpOLT(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name); + } + Value *CreateFCmpOLE(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name); + } + Value *CreateFCmpONE(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name); + } + Value *CreateFCmpORD(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name); + } + Value *CreateFCmpUNO(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name); + } + Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name); + } + Value *CreateFCmpUGT(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name); + } + Value *CreateFCmpUGE(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name); + } + Value *CreateFCmpULT(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name); + } + Value *CreateFCmpULE(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name); + } + Value *CreateFCmpUNE(Value *LHS, Value *RHS, const char *Name = "") { + return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name); + } + + Value *CreateICmp(ICmpInst::Predicate P, Value *LHS, Value *RHS, + const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getCompare(P, LC, RC); + return LLVMBuilder::CreateICmp(P, LHS, RHS, Name); + } + + Value *CreateFCmp(FCmpInst::Predicate P, Value *LHS, Value *RHS, + const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return ConstantExpr::getCompare(P, LC, RC); + return LLVMBuilder::CreateFCmp(P, LHS, RHS, Name); + } +}; } From dpatel at apple.com Tue Oct 9 16:31:37 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 09 Oct 2007 21:31:37 -0000 Subject: [llvm-commits] [llvm] r42812 - /llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Message-ID: <200710092131.l99LVbkI007040@zion.cs.uiuc.edu> Author: dpatel Date: Tue Oct 9 16:31:36 2007 New Revision: 42812 URL: http://llvm.org/viewvc/llvm-project?rev=42812&view=rev Log: Do not walk invalid iterator. Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=42812&r1=42811&r2=42812&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Tue Oct 9 16:31:36 2007 @@ -632,8 +632,8 @@ DominanceFrontier::DomSetType &DFSet = DFI->second; for (DominanceFrontier::DomSetType::iterator DI = DFSet.begin(), - DE = DFSet.end(); DI != DE; ++DI) { - BasicBlock *B = *DI; + DE = DFSet.end(); DI != DE;) { + BasicBlock *B = *DI++; if (L->contains(B)) continue; From clattner at apple.com Tue Oct 9 16:34:23 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 9 Oct 2007 14:34:23 -0700 Subject: [llvm-commits] [llvm] r42806 - /llvm/trunk/include/llvm/Support/LLVMBuilder.h In-Reply-To: <200710091949.l99JnJZ1002769@zion.cs.uiuc.edu> References: <200710091949.l99JnJZ1002769@zion.cs.uiuc.edu> Message-ID: <71B9B981-A555-467B-9571-E9B271DFA53D@apple.com> On Oct 9, 2007, at 12:49 PM, Devang Patel wrote: > + Value *CreateShl(Value *LHS, Value *RHS, const char *Name = "") { > + if (Constant *LC = dyn_cast(LHS)) > + if (Constant *RC = dyn_cast(RHS)) > + return ConstantExpr::getShl(LC, RC); > + return LLVMBuilder::CreateShl(LHS, RHS, Name); > + } Several of these have slightly funky indentation, otherwise looks very nice! -Chris From kremenek at apple.com Tue Oct 9 16:38:09 2007 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 09 Oct 2007 21:38:09 -0000 Subject: [llvm-commits] [llvm] r42813 - in /llvm/trunk/include/llvm/ADT: ImmutableMap.h ImmutableSet.h Message-ID: <200710092138.l99Lc9tX007438@zion.cs.uiuc.edu> Author: kremenek Date: Tue Oct 9 16:38:09 2007 New Revision: 42813 URL: http://llvm.org/viewvc/llvm-project?rev=42813&view=rev Log: Added implementation of immutable (functional) maps and sets, as implemented on top of a functional AVL tree. The AVL balancing code is inspired by the OCaml implementation of Map, which also uses a functional AVL tree. Documentation is currently limited and cleanups are planned, but this code compiles and has been tested. Added: llvm/trunk/include/llvm/ADT/ImmutableMap.h llvm/trunk/include/llvm/ADT/ImmutableSet.h Added: llvm/trunk/include/llvm/ADT/ImmutableMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableMap.h?rev=42813&view=auto ============================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableMap.h (added) +++ llvm/trunk/include/llvm/ADT/ImmutableMap.h Tue Oct 9 16:38:09 2007 @@ -0,0 +1,163 @@ +//===--- ImmutableMap.h - Immutable (functional) map interface --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ImmutableMap class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_IMMAP_H +#define LLVM_ADT_IMMAP_H + +#include "llvm/ADT/ImmutableSet.h" + +namespace llvm { + +/// ImutKeyValueInfo -Traits class used by ImmutableMap. While both the first and +/// second elements in a pair are used to generate profile information, +/// only the first element (the key) is used by isEqual and isLess. +template +struct ImutKeyValueInfo { + typedef const std::pair value_type; + typedef const value_type& value_type_ref; + typedef const T key_type; + typedef const T& key_type_ref; + typedef const S data_type; + typedef const S& data_type_ref; + + static inline key_type_ref KeyOfValue(value_type_ref V) { + return V.first; + } + + static inline bool isEqual(key_type_ref L, key_type_ref R) { + return ImutContainerInfo::isEqual(L,R); + } + + static inline bool isLess(key_type_ref L, key_type_ref R) { + return ImutContainerInfo::isLess(L,R); + } + + static inline void Profile(FoldingSetNodeID& ID, value_type_ref V) { + ImutContainerInfo::Profile(ID, V.first); + ImutContainerInfo::Profile(ID, V.second); + } +}; + + +template > +class ImmutableMap { + typedef typename ValInfo::value_type value_type; + typedef typename ValInfo::value_type_ref value_type_ref; + typedef typename ValInfo::key_type key_type; + typedef typename ValInfo::key_type_ref key_type_ref; + typedef typename ValInfo::data_type data_type; + typedef typename ValInfo::data_type_ref data_type_ref; + +private: + typedef ImutAVLTree TreeTy; + TreeTy* Root; + + ImmutableMap(TreeTy* R) : Root(R) {} + +public: + + class Factory { + typename TreeTy::Factory F; + + public: + Factory() {} + + ImmutableMap GetEmptyMap() { return ImmutableMap(F.GetEmptyTree()); } + + ImmutableMap Add(ImmutableMap Old, key_type_ref K, data_type_ref D) { + return ImmutableMap(F.Add(Old.Root,std::make_pair(K,D))); + } + + ImmutableMap Remove(ImmutableMap Old, key_type_ref K) { + return ImmutableMap(F.Remove(Old.Root,K)); + } + + private: + Factory(const Factory& RHS) {}; + void operator=(const Factory& RHS) {}; + }; + + friend class Factory; + + bool contains(key_type_ref K) const { + return Root ? Root->contains(K) : false; + } + + data_type* find(key_type_ref K) const { + if (Root) { + TreeTy* T = Root->find(K); + if (T) return &T->getValue().second; + } + + return NULL; + } + + bool operator==(ImmutableMap RHS) const { + return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root; + } + + bool operator!=(ImmutableMap RHS) const { + return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root; + } + + bool isEmpty() const { return !Root; } + + //===--------------------------------------------------===// + // Foreach - A limited form of map iteration. + //===--------------------------------------------------===// + +private: + template + struct CBWrapper { + Callback C; + void operator()(value_type_ref V) { C(V.first,V.second); } + }; + + template + struct CBWrapperRef { + Callback &C; + CBWrapperRef(Callback& c) : C(c) {} + + void operator()(value_type_ref V) { C(V.first,V.second); } + }; + +public: + template + void foreach(Callback& C) { + if (Root) { + CBWrapperRef CB(C); + Root->foreach(CB); + } + } + + template + void foreach() { + if (Root) { + CBWrapper CB; + Root->foreach(CB); + } + } + + //===--------------------------------------------------===// + // For testing. + //===--------------------------------------------------===// + + void verify() const { if (Root) Root->verify(); } + unsigned getHeight() const { return Root ? Root->getHeight() : 0; } + +}; + +} // end namespace llvm + +#endif Added: llvm/trunk/include/llvm/ADT/ImmutableSet.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=42813&view=auto ============================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableSet.h (added) +++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Tue Oct 9 16:38:09 2007 @@ -0,0 +1,608 @@ +//===--- ImmutableSet.h - Immutable (functional) set interface --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ImutAVLTree and ImmutableSet classes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_IMSET_H +#define LLVM_ADT_IMSET_H + +#include "llvm/Support/Allocator.h" +#include "llvm/ADT/FoldingSet.h" +#include + +namespace llvm { + +//===----------------------------------------------------------------------===// +// Immutable AVL-Tree Definition. +//===----------------------------------------------------------------------===// + +template class ImutAVLFactory; + +template +class ImutAVLTree : public FoldingSetNode { + struct ComputeIsEqual; +public: + typedef typename ImutInfo::key_type_ref key_type_ref; + typedef typename ImutInfo::value_type value_type; + typedef typename ImutInfo::value_type_ref value_type_ref; + typedef ImutAVLFactory Factory; + friend class ImutAVLFactory; + + //===----------------------------------------------------===// + // Public Interface. + //===----------------------------------------------------===// + + ImutAVLTree* getLeft() const { return reinterpret_cast(Left); } + + ImutAVLTree* getRight() const { return Right; } + + unsigned getHeight() const { return Height; } + + const value_type& getValue() const { return Value; } + + ImutAVLTree* find(key_type_ref K) { + ImutAVLTree *T = this; + + while (T) { + key_type_ref CurrentKey = ImutInfo::KeyOfValue(Value(T)); + + if (ImutInfo::isEqual(K,CurrentKey)) + return T; + else if (ImutInfo::isLess(K,CurrentKey)) + T = T->getLeft(); + else + T = T->getRight(); + } + + return NULL; + } + + unsigned size() const { + unsigned n = 1; + + if (const ImutAVLTree* L = getLeft()) n += L->size(); + if (const ImutAVLTree* R = getRight()) n += R->size(); + + return n; + } + + + + bool isEqual(const ImutAVLTree& RHS) const { + // FIXME: Todo. + return true; + } + + bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual(RHS); } + + bool contains(const key_type_ref K) { return (bool) find(K); } + + template + void foreach(Callback& C) { + if (ImutAVLTree* L = getLeft()) L->foreach(C); + + C(Value); + + if (ImutAVLTree* R = getRight()) R->foreach(C); + } + + unsigned verify() const { + unsigned HL = getLeft() ? getLeft()->verify() : 0; + unsigned HR = getRight() ? getRight()->verify() : 0; + + assert (getHeight() == ( HL > HR ? HL : HR ) + 1 + && "Height calculation wrong."); + + assert ((HL > HR ? HL-HR : HR-HL) <= 2 + && "Balancing invariant violated."); + + + assert (!getLeft() + || ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()), + ImutInfo::KeyOfValue(getValue())) + && "Value in left child is not less that current value."); + + + assert (!getRight() + || ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()), + ImutInfo::KeyOfValue(getRight()->getValue())) + && "Current value is not less that value of right child."); + + return getHeight(); + } + + //===----------------------------------------------------===// + // Internal Values. + //===----------------------------------------------------===// + +private: + uintptr_t Left; + ImutAVLTree* Right; + unsigned Height; + value_type Value; + + //===----------------------------------------------------===// + // Profiling or FoldingSet. + //===----------------------------------------------------===// + + static inline + void Profile(FoldingSetNodeID& ID, ImutAVLTree* L, ImutAVLTree* R, + unsigned H, value_type_ref V) { + ID.AddPointer(L); + ID.AddPointer(R); + ID.AddInteger(H); + ImutInfo::Profile(ID,V); + } + +public: + + void Profile(FoldingSetNodeID& ID) { + Profile(ID,getSafeLeft(),getRight(),getHeight(),getValue()); + } + + //===----------------------------------------------------===// + // Internal methods (node manipulation; used by Factory). + //===----------------------------------------------------===// + +private: + + ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, unsigned height) + : Left(reinterpret_cast(l) | 0x1), + Right(r), Height(height), Value(v) {} + + bool isMutable() const { return Left & 0x1; } + + ImutAVLTree* getSafeLeft() const { + return reinterpret_cast(Left & ~0x1); + } + + // Mutating operations. A tree root can be manipulated as long as + // its reference has not "escaped" from internal methods of a + // factory object (see below). When a tree pointer is externally + // viewable by client code, the internal "mutable bit" is cleared + // to mark the tree immutable. Note that a tree that still has + // its mutable bit set may have children (subtrees) that are themselves + // immutable. + + void RemoveMutableFlag() { + assert (Left & 0x1 && "Mutable flag already removed."); + Left &= ~0x1; + } + + void setLeft(ImutAVLTree* NewLeft) { + assert (isMutable()); + Left = reinterpret_cast(NewLeft) | 0x1; + } + + void setRight(ImutAVLTree* NewRight) { + assert (isMutable()); + Right = NewRight; + } + + void setHeight(unsigned h) { + assert (isMutable()); + Height = h; + } +}; + +//===----------------------------------------------------------------------===// +// Immutable AVL-Tree Factory class. +//===----------------------------------------------------------------------===// + +template +class ImutAVLFactory { + typedef ImutAVLTree TreeTy; + typedef typename TreeTy::value_type_ref value_type_ref; + typedef typename TreeTy::key_type_ref key_type_ref; + + typedef FoldingSet CacheTy; + + CacheTy Cache; + BumpPtrAllocator Allocator; + + //===--------------------------------------------------===// + // Public interface. + //===--------------------------------------------------===// + +public: + ImutAVLFactory() {} + + TreeTy* Add(TreeTy* T, value_type_ref V) { + T = Add_internal(V,T); + MarkImmutable(T); + return T; + } + + TreeTy* Remove(TreeTy* T, key_type_ref V) { + T = Remove_internal(V,T); + MarkImmutable(T); + return T; + } + + TreeTy* GetEmptyTree() const { return NULL; } + + //===--------------------------------------------------===// + // A bunch of quick helper functions used for reasoning + // about the properties of trees and their children. + // These have succinct names so that the balancing code + // is as terse (and readable) as possible. + //===--------------------------------------------------===// +private: + + bool isEmpty(TreeTy* T) const { + return !T; + } + + unsigned Height(TreeTy* T) const { + return T ? T->getHeight() : 0; + } + + TreeTy* Left(TreeTy* T) const { + assert (T); + return T->getSafeLeft(); + } + + TreeTy* Right(TreeTy* T) const { + assert (T); + return T->getRight(); + } + + value_type_ref Value(TreeTy* T) const { + assert (T); + return T->Value; + } + + unsigned IncrementHeight(TreeTy* L, TreeTy* R) const { + unsigned hl = Height(L); + unsigned hr = Height(R); + return ( hl > hr ? hl : hr ) + 1; + } + + //===--------------------------------------------------===// + // "Create" is used to generate new tree roots that link + // to other trees. The functon may also simply move links + // in an existing root if that root is still marked mutable. + // This is necessary because otherwise our balancing code + // would leak memory as it would create nodes that are + // then discarded later before the finished tree is + // returned to the caller. + //===--------------------------------------------------===// + + TreeTy* Create(TreeTy* L, value_type_ref V, TreeTy* R) { + FoldingSetNodeID ID; + unsigned height = IncrementHeight(L,R); + + TreeTy::Profile(ID,L,R,height,V); + void* InsertPos; + + if (TreeTy* T = Cache.FindNodeOrInsertPos(ID,InsertPos)) + return T; + + assert (InsertPos != NULL); + + // FIXME: more intelligent calculation of alignment. + TreeTy* T = (TreeTy*) Allocator.Allocate(sizeof(*T),16); + new (T) TreeTy(L,R,V,height); + + Cache.InsertNode(T,InsertPos); + return T; + } + + TreeTy* Create(TreeTy* L, TreeTy* OldTree, TreeTy* R) { + assert (!isEmpty(OldTree)); + + if (OldTree->isMutable()) { + OldTree->setLeft(L); + OldTree->setRight(R); + OldTree->setHeight(IncrementHeight(L,R)); + return OldTree; + } + else return Create(L, Value(OldTree), R); + } + + /// Balance - Used by Add_internal and Remove_internal to + /// balance a newly created tree. + TreeTy* Balance(TreeTy* L, value_type_ref V, TreeTy* R) { + + unsigned hl = Height(L); + unsigned hr = Height(R); + + if (hl > hr + 2) { + assert (!isEmpty(L) && + "Left tree cannot be empty to have a height >= 2."); + + TreeTy* LL = Left(L); + TreeTy* LR = Right(L); + + if (Height(LL) >= Height(LR)) + return Create(LL, L, Create(LR,V,R)); + + assert (!isEmpty(LR) && + "LR cannot be empty because it has a height >= 1."); + + TreeTy* LRL = Left(LR); + TreeTy* LRR = Right(LR); + + return Create(Create(LL,L,LRL), LR, Create(LRR,V,R)); + } + else if (hr > hl + 2) { + assert (!isEmpty(R) && + "Right tree cannot be empty to have a height >= 2."); + + TreeTy* RL = Left(R); + TreeTy* RR = Right(R); + + if (Height(RR) >= Height(RL)) + return Create(Create(L,V,RL), R, RR); + + assert (!isEmpty(RL) && + "RL cannot be empty because it has a height >= 1."); + + TreeTy* RLL = Left(RL); + TreeTy* RLR = Right(RL); + + return Create(Create(L,V,RLL), RL, Create(RLR,R,RR)); + } + else + return Create(L,V,R); + } + + /// Add_internal - Creates a new tree that includes the specified + /// data and the data from the original tree. If the original tree + /// already contained the data item, the original tree is returned. + TreeTy* Add_internal(value_type_ref V, TreeTy* T) { + if (isEmpty(T)) + return Create(T, V, T); + + assert (!T->isMutable()); + + key_type_ref K = ImutInfo::KeyOfValue(V); + key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T)); + + if (ImutInfo::isEqual(K,KCurrent)) + return Create(Left(T), V, Right(T)); + else if (ImutInfo::isLess(K,KCurrent)) + return Balance(Add_internal(V,Left(T)), Value(T), Right(T)); + else + return Balance(Left(T), Value(T), Add_internal(V,Right(T))); + } + + /// Remove_interal - Creates a new tree that includes all the data + /// from the original tree except the specified data. If the + /// specified data did not exist in the original tree, the original + /// tree is returned. + TreeTy* Remove_internal(key_type_ref K, TreeTy* T) { + if (isEmpty(T)) + return T; + + assert (!T->isMutable()); + + key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T)); + + if (ImutInfo::isEqual(K,KCurrent)) + return CombineLeftRightTrees(Left(T),Right(T)); + else if (ImutInfo::isLess(K,KCurrent)) + return Balance(Remove_internal(K,Left(T)), Value(T), Right(T)); + else + return Balance(Left(T), Value(T), Remove_internal(K,Right(T))); + } + + TreeTy* CombineLeftRightTrees(TreeTy* L, TreeTy* R) { + if (isEmpty(L)) return R; + if (isEmpty(R)) return L; + + TreeTy* OldNode; + TreeTy* NewRight = RemoveMinBinding(R,OldNode); + return Balance(L,Value(OldNode),NewRight); + } + + TreeTy* RemoveMinBinding(TreeTy* T, TreeTy*& NodeRemoved) { + assert (!isEmpty(T)); + + if (isEmpty(Left(T))) { + NodeRemoved = T; + return Right(T); + } + + return Balance(RemoveMinBinding(Left(T),NodeRemoved),Value(T),Right(T)); + } + + /// MarkImmutable - Clears the mutable bits of a root and all of its + /// descendants. + void MarkImmutable(TreeTy* T) { + if (!T || !T->isMutable()) + return; + + T->RemoveMutableFlag(); + MarkImmutable(Left(T)); + MarkImmutable(Right(T)); + } +}; + + +//===----------------------------------------------------------------------===// +// Trait classes for Profile information. +//===----------------------------------------------------------------------===// + +/// Generic profile template. The default behavior is to invoke the +/// profile method of an object. Specializations for primitive integers +/// and generic handling of pointers is done below. +template +struct ImutProfileInfo { + typedef const T value_type; + typedef const T& value_type_ref; + + static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) { + X.Profile(ID); + } +}; + +/// Profile traits for integers. +template +struct ImutProfileInteger { + typedef const T value_type; + typedef const T& value_type_ref; + + static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) { + ID.AddInteger(X); + } +}; + +#define PROFILE_INTEGER_INFO(X)\ +template<> struct ImutProfileInfo : ImutProfileInteger {}; + +PROFILE_INTEGER_INFO(char) +PROFILE_INTEGER_INFO(unsigned char) +PROFILE_INTEGER_INFO(short) +PROFILE_INTEGER_INFO(unsigned short) +PROFILE_INTEGER_INFO(unsigned) +PROFILE_INTEGER_INFO(signed) +PROFILE_INTEGER_INFO(long) +PROFILE_INTEGER_INFO(unsigned long) +PROFILE_INTEGER_INFO(long long) +PROFILE_INTEGER_INFO(unsigned long long) + +#undef PROFILE_INTEGER_INFO + +/// Generic profile trait for pointer types. We treat pointers as +/// references to unique objects. +template +struct ImutProfileInfo { + typedef const T* value_type; + typedef value_type value_type_ref; + + static inline void Profile(FoldingSetNodeID &ID, value_type_ref X) { + ID.AddPointer(X); + } +}; + +//===----------------------------------------------------------------------===// +// Trait classes that contain element comparison operators and type +// definitions used by ImutAVLTree, ImmutableSet, and ImmutableMap. These +// inherit from the profile traits (ImutProfileInfo) to include operations +// for element profiling. +//===----------------------------------------------------------------------===// + + +/// ImutContainerInfo - Generic definition of comparison operations for +/// elements of immutable containers that defaults to using +/// std::equal_to<> and std::less<> to perform comparison of elements. +template +struct ImutContainerInfo : public ImutProfileInfo { + typedef typename ImutProfileInfo::value_type value_type; + typedef typename ImutProfileInfo::value_type_ref value_type_ref; + typedef value_type key_type; + typedef value_type_ref key_type_ref; + + static inline key_type_ref KeyOfValue(value_type_ref D) { return D; } + + static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) { + return std::equal_to()(LHS,RHS); + } + + static inline bool isLess(key_type_ref LHS, key_type_ref RHS) { + return std::less()(LHS,RHS); + } +}; + +/// ImutContainerInfo - Specialization for pointer values to treat pointers +/// as references to unique objects. Pointers are thus compared by +/// their addresses. +template +struct ImutContainerInfo : public ImutProfileInfo { + typedef typename ImutProfileInfo::value_type value_type; + typedef typename ImutProfileInfo::value_type_ref value_type_ref; + typedef value_type key_type; + typedef value_type_ref key_type_ref; + + static inline key_type_ref KeyOfValue(value_type_ref D) { return D; } + + static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) { + return LHS == RHS; + } + + static inline bool isLess(key_type_ref LHS, key_type_ref RHS) { + return LHS < RHS; + } +}; + +//===----------------------------------------------------------------------===// +// Immutable Set +//===----------------------------------------------------------------------===// + +template > +class ImmutableSet { +public: + typedef typename ValInfo::value_type value_type; + typedef typename ValInfo::value_type_ref value_type_ref; + +private: + typedef ImutAVLTree TreeTy; + TreeTy* Root; + + ImmutableSet(TreeTy* R) : Root(R) {} + +public: + + class Factory { + typename TreeTy::Factory F; + + public: + Factory() {} + + ImmutableSet GetEmptySet() { return ImmutableSet(F.GetEmptyTree()); } + + ImmutableSet Add(ImmutableSet Old, value_type_ref V) { + return ImmutableSet(F.Add(Old.Root,V)); + } + + ImmutableSet Remove(ImmutableSet Old, value_type_ref V) { + return ImmutableSet(F.Remove(Old.Root,V)); + } + + private: + Factory(const Factory& RHS) {}; + void operator=(const Factory& RHS) {}; + }; + + friend class Factory; + + bool contains(const value_type_ref V) const { + return Root ? Root->contains(V) : false; + } + + bool operator==(ImmutableSet RHS) const { + return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root; + } + + bool operator!=(ImmutableSet RHS) const { + return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root; + } + + bool isEmpty() const { return !Root; } + + template + void foreach(Callback& C) { if (Root) Root->foreach(C); } + + template + void foreach() { if (Root) { Callback C; Root->foreach(C); } } + + //===--------------------------------------------------===// + // For testing. + //===--------------------------------------------------===// + + void verify() const { if (Root) Root->verify(); } + unsigned getHeight() const { return Root ? Root->getHeight() : 0; } +}; + +} // end namespace llvm + +#endif From dpatel at apple.com Tue Oct 9 16:41:01 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 09 Oct 2007 21:41:01 -0000 Subject: [llvm-commits] [llvm] r42814 - /llvm/trunk/include/llvm/Support/LLVMBuilder.h Message-ID: <200710092141.l99Lf1pb007579@zion.cs.uiuc.edu> Author: dpatel Date: Tue Oct 9 16:41:00 2007 New Revision: 42814 URL: http://llvm.org/viewvc/llvm-project?rev=42814&view=rev Log: Fix indentation. Modified: llvm/trunk/include/llvm/Support/LLVMBuilder.h Modified: llvm/trunk/include/llvm/Support/LLVMBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/LLVMBuilder.h?rev=42814&r1=42813&r2=42814&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/LLVMBuilder.h (original) +++ llvm/trunk/include/llvm/Support/LLVMBuilder.h Tue Oct 9 16:41:00 2007 @@ -517,26 +517,26 @@ } Value *CreateShl(Value *LHS, Value *RHS, const char *Name = "") { - if (Constant *LC = dyn_cast(LHS)) + if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) return ConstantExpr::getShl(LC, RC); return LLVMBuilder::CreateShl(LHS, RHS, Name); } Value *CreateLShr(Value *LHS, Value *RHS, const char *Name = "") { - if (Constant *LC = dyn_cast(LHS)) + if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) return ConstantExpr::getLShr(LC, RC); return LLVMBuilder::CreateLShr(LHS, RHS, Name); } Value *CreateAShr(Value *LHS, Value *RHS, const char *Name = "") { - if (Constant *LC = dyn_cast(LHS)) + if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) return ConstantExpr::getAShr(LC, RC); return LLVMBuilder::CreateAShr(LHS, RHS, Name); } - + //===--------------------------------------------------------------------===// // Instruction creation methods: Compare Instructions //===--------------------------------------------------------------------===// @@ -617,7 +617,7 @@ Value *CreateICmp(ICmpInst::Predicate P, Value *LHS, Value *RHS, const char *Name = "") { - if (Constant *LC = dyn_cast(LHS)) + if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) return ConstantExpr::getCompare(P, LC, RC); return LLVMBuilder::CreateICmp(P, LHS, RHS, Name); @@ -625,7 +625,7 @@ Value *CreateFCmp(FCmpInst::Predicate P, Value *LHS, Value *RHS, const char *Name = "") { - if (Constant *LC = dyn_cast(LHS)) + if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) return ConstantExpr::getCompare(P, LC, RC); return LLVMBuilder::CreateFCmp(P, LHS, RHS, Name); From sabre at nondot.org Tue Oct 9 16:46:38 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 09 Oct 2007 21:46:38 -0000 Subject: [llvm-commits] [llvm] r42815 - in /llvm/trunk: include/llvm/Support/MemoryBuffer.h lib/Support/MemoryBuffer.cpp Message-ID: <200710092146.l99LkcMu007833@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 9 16:46:38 2007 New Revision: 42815 URL: http://llvm.org/viewvc/llvm-project?rev=42815&view=rev Log: Add new MemoryBuffer::getMemBufferCopy method. Modified: llvm/trunk/include/llvm/Support/MemoryBuffer.h llvm/trunk/lib/Support/MemoryBuffer.cpp Modified: llvm/trunk/include/llvm/Support/MemoryBuffer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MemoryBuffer.h?rev=42815&r1=42814&r2=42815&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/MemoryBuffer.h (original) +++ llvm/trunk/include/llvm/Support/MemoryBuffer.h Tue Oct 9 16:46:38 2007 @@ -61,6 +61,12 @@ static MemoryBuffer *getMemBuffer(const char *StartPtr, const char *EndPtr, const char *BufferName = ""); + /// getMemBufferCopy - Open the specified memory range as a MemoryBuffer, + /// copying the contents and taking ownership of it. This has no requirements + /// on EndPtr[0]. + static MemoryBuffer *getMemBufferCopy(const char *StartPtr,const char *EndPtr, + const char *BufferName = ""); + /// getNewMemBuffer - Allocate a new MemoryBuffer of the specified size that /// is completely initialized to zeros. Note that the caller should /// initialize the memory allocated by this method. The memory is owned by Modified: llvm/trunk/lib/Support/MemoryBuffer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/MemoryBuffer.cpp?rev=42815&r1=42814&r2=42815&view=diff ============================================================================== --- llvm/trunk/lib/Support/MemoryBuffer.cpp (original) +++ llvm/trunk/lib/Support/MemoryBuffer.cpp Tue Oct 9 16:46:38 2007 @@ -59,9 +59,13 @@ class MemoryBufferMem : public MemoryBuffer { std::string FileID; public: - MemoryBufferMem(const char *Start, const char *End, const char *FID) + MemoryBufferMem(const char *Start, const char *End, const char *FID, + bool Copy = false) : FileID(FID) { - init(Start, End); + if (!Copy) + init(Start, End); + else + initCopyOf(Start, End); } virtual const char *getBufferIdentifier() const { @@ -78,6 +82,15 @@ return new MemoryBufferMem(StartPtr, EndPtr, BufferName); } +/// getMemBufferCopy - Open the specified memory range as a MemoryBuffer, +/// copying the contents and taking ownership of it. This has no requirements +/// on EndPtr[0]. +MemoryBuffer *MemoryBuffer::getMemBufferCopy(const char *StartPtr, + const char *EndPtr, + const char *BufferName) { + return new MemoryBufferMem(StartPtr, EndPtr, BufferName, true); +} + /// getNewUninitMemBuffer - Allocate a new MemoryBuffer of the specified size /// that is completely initialized to zeros. Note that the caller should /// initialize the memory allocated by this method. The memory is owned by From kremenek at apple.com Tue Oct 9 16:49:50 2007 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 09 Oct 2007 21:49:50 -0000 Subject: [llvm-commits] [llvm] r42816 - /llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Message-ID: <200710092149.l99LnoB7007963@zion.cs.uiuc.edu> Author: kremenek Date: Tue Oct 9 16:49:49 2007 New Revision: 42816 URL: http://llvm.org/viewvc/llvm-project?rev=42816&view=rev Log: Modified XCode project to contain... ADT/DenseSet.h ADT/ImmutableMap.h ADT/ImmutableSet.h Modified: llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Modified: llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj?rev=42816&r1=42815&r2=42816&view=diff ============================================================================== --- llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj (original) +++ llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Tue Oct 9 16:49:49 2007 @@ -65,6 +65,9 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 35E98A830CBC2ED300C5CDC1 /* DenseSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DenseSet.h; sourceTree = ""; }; + 35E98A840CBC2ED300C5CDC1 /* ImmutableMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImmutableMap.h; sourceTree = ""; }; + 35E98A850CBC2ED300C5CDC1 /* ImmutableSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImmutableSet.h; sourceTree = ""; }; 84115FFE0B66D87400E1293E /* TargetMachOWriterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetMachOWriterInfo.cpp; sourceTree = ""; }; 84115FFF0B66D89B00E1293E /* PPCMachOWriterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PPCMachOWriterInfo.cpp; sourceTree = ""; }; 841160000B66D8AC00E1293E /* PPCMachOWriterInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCMachOWriterInfo.h; sourceTree = ""; }; @@ -2162,6 +2165,9 @@ DE66F1EB08ABF03100323D32 /* ADT */ = { isa = PBXGroup; children = ( + 35E98A830CBC2ED300C5CDC1 /* DenseSet.h */, + 35E98A840CBC2ED300C5CDC1 /* ImmutableMap.h */, + 35E98A850CBC2ED300C5CDC1 /* ImmutableSet.h */, 9FA638DD0C77B1AB007F12AE /* BitVector.h */, DE66F1EE08ABF03100323D32 /* DenseMap.h */, DE66F1EF08ABF03100323D32 /* DepthFirstIterator.h */, @@ -2772,6 +2778,7 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = DE66EC5008ABE78900323D32 /* Build configuration list for PBXProject "LLVM" */; + compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 08FB7794FE84155DC02AAC07 /* LLVM */; projectDirPath = ""; From lattner at apple.com Tue Oct 9 17:04:20 2007 From: lattner at apple.com (Tanya Lattner) Date: Tue, 9 Oct 2007 15:04:20 -0700 Subject: [llvm-commits] [llvm] r42813 - in /llvm/trunk/include/llvm/ADT: ImmutableMap.h ImmutableSet.h In-Reply-To: <200710092138.l99Lc9tX007438@zion.cs.uiuc.edu> References: <200710092138.l99Lc9tX007438@zion.cs.uiuc.edu> Message-ID: <8DF233DB-923F-4E52-9919-F26050BE437A@apple.com> On Oct 9, 2007, at 2:38 PM, Ted Kremenek wrote: > Author: kremenek > Date: Tue Oct 9 16:38:09 2007 > New Revision: 42813 > > URL: http://llvm.org/viewvc/llvm-project?rev=42813&view=rev > Log: > Added implementation of immutable (functional) maps and sets, as > implemented on top of a functional AVL tree. The AVL balancing code > is inspired by the OCaml implementation of Map, which also uses a > functional > AVL tree. > > Documentation is currently limited and cleanups are planned, but > this code > compiles and has been tested. > You mention that documentation is limited, so this may be a stupid question. Do you plan to add doxygen style comments to each function providing a brief description of it? Thanks, Tanya > Added: > llvm/trunk/include/llvm/ADT/ImmutableMap.h > llvm/trunk/include/llvm/ADT/ImmutableSet.h > > Added: llvm/trunk/include/llvm/ADT/ImmutableMap.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ > ADT/ImmutableMap.h?rev=42813&view=auto > > ====================================================================== > ======== > --- llvm/trunk/include/llvm/ADT/ImmutableMap.h (added) > +++ llvm/trunk/include/llvm/ADT/ImmutableMap.h Tue Oct 9 16:38:09 > 2007 > @@ -0,0 +1,163 @@ > +//===--- ImmutableMap.h - Immutable (functional) map interface -- > *- C++ -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file was developed by Ted Kremenek and is distributed under > +// the University of Illinois Open Source License. See LICENSE.TXT > for details. > +// > +// > ===------------------------------------------------------------------- > ---===// > +// > +// This file defines the ImmutableMap class. > +// > +// > ===------------------------------------------------------------------- > ---===// > + > +#ifndef LLVM_ADT_IMMAP_H > +#define LLVM_ADT_IMMAP_H > + > +#include "llvm/ADT/ImmutableSet.h" > + > +namespace llvm { > + > +/// ImutKeyValueInfo -Traits class used by ImmutableMap. While > both the first and > +/// second elements in a pair are used to generate profile > information, > +/// only the first element (the key) is used by isEqual and isLess. > +template > +struct ImutKeyValueInfo { > + typedef const std::pair value_type; > + typedef const value_type& value_type_ref; > + typedef const T key_type; > + typedef const T& key_type_ref; > + typedef const S data_type; > + typedef const S& data_type_ref; > + > + static inline key_type_ref KeyOfValue(value_type_ref V) { > + return V.first; > + } > + > + static inline bool isEqual(key_type_ref L, key_type_ref R) { > + return ImutContainerInfo::isEqual(L,R); > + } > + > + static inline bool isLess(key_type_ref L, key_type_ref R) { > + return ImutContainerInfo::isLess(L,R); > + } > + > + static inline void Profile(FoldingSetNodeID& ID, value_type_ref > V) { > + ImutContainerInfo::Profile(ID, V.first); > + ImutContainerInfo::Profile(ID, V.second); > + } > +}; > + > + > +template + typename ValInfo = ImutKeyValueInfo > > +class ImmutableMap { > + typedef typename ValInfo::value_type value_type; > + typedef typename ValInfo::value_type_ref value_type_ref; > + typedef typename ValInfo::key_type key_type; > + typedef typename ValInfo::key_type_ref key_type_ref; > + typedef typename ValInfo::data_type data_type; > + typedef typename ValInfo::data_type_ref data_type_ref; > + > +private: > + typedef ImutAVLTree TreeTy; > + TreeTy* Root; > + > + ImmutableMap(TreeTy* R) : Root(R) {} > + > +public: > + > + class Factory { > + typename TreeTy::Factory F; > + > + public: > + Factory() {} > + > + ImmutableMap GetEmptyMap() { return ImmutableMap(F.GetEmptyTree > ()); } > + > + ImmutableMap Add(ImmutableMap Old, key_type_ref K, > data_type_ref D) { > + return ImmutableMap(F.Add > (Old.Root,std::make_pair(K,D))); > + } > + > + ImmutableMap Remove(ImmutableMap Old, key_type_ref K) { > + return ImmutableMap(F.Remove(Old.Root,K)); > + } > + > + private: > + Factory(const Factory& RHS) {}; > + void operator=(const Factory& RHS) {}; > + }; > + > + friend class Factory; > + > + bool contains(key_type_ref K) const { > + return Root ? Root->contains(K) : false; > + } > + > + data_type* find(key_type_ref K) const { > + if (Root) { > + TreeTy* T = Root->find(K); > + if (T) return &T->getValue().second; > + } > + > + return NULL; > + } > + > + bool operator==(ImmutableMap RHS) const { > + return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == > RHS.Root; > + } > + > + bool operator!=(ImmutableMap RHS) const { > + return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root ! > = RHS.Root; > + } > + > + bool isEmpty() const { return !Root; } > + > + //===--------------------------------------------------===// > + // Foreach - A limited form of map iteration. > + //===--------------------------------------------------===// > + > +private: > + template > + struct CBWrapper { > + Callback C; > + void operator()(value_type_ref V) { C(V.first,V.second); } > + }; > + > + template > + struct CBWrapperRef { > + Callback &C; > + CBWrapperRef(Callback& c) : C(c) {} > + > + void operator()(value_type_ref V) { C(V.first,V.second); } > + }; > + > +public: > + template > + void foreach(Callback& C) { > + if (Root) { > + CBWrapperRef CB(C); > + Root->foreach(CB); > + } > + } > + > + template > + void foreach() { > + if (Root) { > + CBWrapper CB; > + Root->foreach(CB); > + } > + } > + > + //===--------------------------------------------------===// > + // For testing. > + //===--------------------------------------------------===// > + > + void verify() const { if (Root) Root->verify(); } > + unsigned getHeight() const { return Root ? Root->getHeight() : 0; } > + > +}; > + > +} // end namespace llvm > + > +#endif > > Added: llvm/trunk/include/llvm/ADT/ImmutableSet.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ > ADT/ImmutableSet.h?rev=42813&view=auto > > ====================================================================== > ======== > --- llvm/trunk/include/llvm/ADT/ImmutableSet.h (added) > +++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Tue Oct 9 16:38:09 > 2007 > @@ -0,0 +1,608 @@ > +//===--- ImmutableSet.h - Immutable (functional) set interface -- > *- C++ -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file was developed by Ted Kremenek and is distributed under > +// the University of Illinois Open Source License. See LICENSE.TXT > for details. > +// > +// > ===------------------------------------------------------------------- > ---===// > +// > +// This file defines the ImutAVLTree and ImmutableSet classes. > +// > +// > ===------------------------------------------------------------------- > ---===// > + > +#ifndef LLVM_ADT_IMSET_H > +#define LLVM_ADT_IMSET_H > + > +#include "llvm/Support/Allocator.h" > +#include "llvm/ADT/FoldingSet.h" > +#include > + > +namespace llvm { > + > +// > ===------------------------------------------------------------------- > ---===// > +// Immutable AVL-Tree Definition. > +// > ===------------------------------------------------------------------- > ---===// > + > +template class ImutAVLFactory; > + > +template > +class ImutAVLTree : public FoldingSetNode { > + struct ComputeIsEqual; > +public: > + typedef typename ImutInfo::key_type_ref key_type_ref; > + typedef typename ImutInfo::value_type value_type; > + typedef typename ImutInfo::value_type_ref value_type_ref; > + typedef ImutAVLFactory Factory; > + friend class ImutAVLFactory; > + > + //===----------------------------------------------------===// > + // Public Interface. > + //===----------------------------------------------------===// > + > + ImutAVLTree* getLeft() const { return > reinterpret_cast(Left); } > + > + ImutAVLTree* getRight() const { return Right; } > + > + unsigned getHeight() const { return Height; } > + > + const value_type& getValue() const { return Value; } > + > + ImutAVLTree* find(key_type_ref K) { > + ImutAVLTree *T = this; > + > + while (T) { > + key_type_ref CurrentKey = ImutInfo::KeyOfValue(Value(T)); > + > + if (ImutInfo::isEqual(K,CurrentKey)) > + return T; > + else if (ImutInfo::isLess(K,CurrentKey)) > + T = T->getLeft(); > + else > + T = T->getRight(); > + } > + > + return NULL; > + } > + > + unsigned size() const { > + unsigned n = 1; > + > + if (const ImutAVLTree* L = getLeft()) n += L->size(); > + if (const ImutAVLTree* R = getRight()) n += R->size(); > + > + return n; > + } > + > + > + > + bool isEqual(const ImutAVLTree& RHS) const { > + // FIXME: Todo. > + return true; > + } > + > + bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual > (RHS); } > + > + bool contains(const key_type_ref K) { return (bool) find(K); } > + > + template > + void foreach(Callback& C) { > + if (ImutAVLTree* L = getLeft()) L->foreach(C); > + > + C(Value); > + > + if (ImutAVLTree* R = getRight()) R->foreach(C); > + } > + > + unsigned verify() const { > + unsigned HL = getLeft() ? getLeft()->verify() : 0; > + unsigned HR = getRight() ? getRight()->verify() : 0; > + > + assert (getHeight() == ( HL > HR ? HL : HR ) + 1 > + && "Height calculation wrong."); > + > + assert ((HL > HR ? HL-HR : HR-HL) <= 2 > + && "Balancing invariant violated."); > + > + > + assert (!getLeft() > + || ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()- > >getValue()), > + ImutInfo::KeyOfValue(getValue())) > + && "Value in left child is not less that current > value."); > + > + > + assert (!getRight() > + || ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()), > + ImutInfo::KeyOfValue(getRight()- > >getValue())) > + && "Current value is not less that value of right > child."); > + > + return getHeight(); > + } > + > + //===----------------------------------------------------===// > + // Internal Values. > + //===----------------------------------------------------===// > + > +private: > + uintptr_t Left; > + ImutAVLTree* Right; > + unsigned Height; > + value_type Value; > + > + //===----------------------------------------------------===// > + // Profiling or FoldingSet. > + //===----------------------------------------------------===// > + > + static inline > + void Profile(FoldingSetNodeID& ID, ImutAVLTree* L, ImutAVLTree* R, > + unsigned H, value_type_ref V) { > + ID.AddPointer(L); > + ID.AddPointer(R); > + ID.AddInteger(H); > + ImutInfo::Profile(ID,V); > + } > + > +public: > + > + void Profile(FoldingSetNodeID& ID) { > + Profile(ID,getSafeLeft(),getRight(),getHeight(),getValue()); > + } > + > + //===----------------------------------------------------===// > + // Internal methods (node manipulation; used by Factory). > + //===----------------------------------------------------===// > + > +private: > + > + ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, > unsigned height) > + : Left(reinterpret_cast(l) | 0x1), > + Right(r), Height(height), Value(v) {} > + > + bool isMutable() const { return Left & 0x1; } > + > + ImutAVLTree* getSafeLeft() const { > + return reinterpret_cast(Left & ~0x1); > + } > + > + // Mutating operations. A tree root can be manipulated as long as > + // its reference has not "escaped" from internal methods of a > + // factory object (see below). When a tree pointer is externally > + // viewable by client code, the internal "mutable bit" is cleared > + // to mark the tree immutable. Note that a tree that still has > + // its mutable bit set may have children (subtrees) that are > themselves > + // immutable. > + > + void RemoveMutableFlag() { > + assert (Left & 0x1 && "Mutable flag already removed."); > + Left &= ~0x1; > + } > + > + void setLeft(ImutAVLTree* NewLeft) { > + assert (isMutable()); > + Left = reinterpret_cast(NewLeft) | 0x1; > + } > + > + void setRight(ImutAVLTree* NewRight) { > + assert (isMutable()); > + Right = NewRight; > + } > + > + void setHeight(unsigned h) { > + assert (isMutable()); > + Height = h; > + } > +}; > + > +// > ===------------------------------------------------------------------- > ---===// > +// Immutable AVL-Tree Factory class. > +// > ===------------------------------------------------------------------- > ---===// > + > +template > +class ImutAVLFactory { > + typedef ImutAVLTree TreeTy; > + typedef typename TreeTy::value_type_ref value_type_ref; > + typedef typename TreeTy::key_type_ref key_type_ref; > + > + typedef FoldingSet CacheTy; > + > + CacheTy Cache; > + BumpPtrAllocator Allocator; > + > + //===--------------------------------------------------===// > + // Public interface. > + //===--------------------------------------------------===// > + > +public: > + ImutAVLFactory() {} > + > + TreeTy* Add(TreeTy* T, value_type_ref V) { > + T = Add_internal(V,T); > + MarkImmutable(T); > + return T; > + } > + > + TreeTy* Remove(TreeTy* T, key_type_ref V) { > + T = Remove_internal(V,T); > + MarkImmutable(T); > + return T; > + } > + > + TreeTy* GetEmptyTree() const { return NULL; } > + > + //===--------------------------------------------------===// > + // A bunch of quick helper functions used for reasoning > + // about the properties of trees and their children. > + // These have succinct names so that the balancing code > + // is as terse (and readable) as possible. > + //===--------------------------------------------------===// > +private: > + > + bool isEmpty(TreeTy* T) const { > + return !T; > + } > + > + unsigned Height(TreeTy* T) const { > + return T ? T->getHeight() : 0; > + } > + > + TreeTy* Left(TreeTy* T) const { > + assert (T); > + return T->getSafeLeft(); > + } > + > + TreeTy* Right(TreeTy* T) const { > + assert (T); > + return T->getRight(); > + } > + > + value_type_ref Value(TreeTy* T) const { > + assert (T); > + return T->Value; > + } > + > + unsigned IncrementHeight(TreeTy* L, TreeTy* R) const { > + unsigned hl = Height(L); > + unsigned hr = Height(R); > + return ( hl > hr ? hl : hr ) + 1; > + } > + > + //===--------------------------------------------------===// > + // "Create" is used to generate new tree roots that link > + // to other trees. The functon may also simply move links > + // in an existing root if that root is still marked mutable. > + // This is necessary because otherwise our balancing code > + // would leak memory as it would create nodes that are > + // then discarded later before the finished tree is > + // returned to the caller. > + //===--------------------------------------------------===// > + > + TreeTy* Create(TreeTy* L, value_type_ref V, TreeTy* R) { > + FoldingSetNodeID ID; > + unsigned height = IncrementHeight(L,R); > + > + TreeTy::Profile(ID,L,R,height,V); > + void* InsertPos; > + > + if (TreeTy* T = Cache.FindNodeOrInsertPos(ID,InsertPos)) > + return T; > + > + assert (InsertPos != NULL); > + > + // FIXME: more intelligent calculation of alignment. > + TreeTy* T = (TreeTy*) Allocator.Allocate(sizeof(*T),16); > + new (T) TreeTy(L,R,V,height); > + > + Cache.InsertNode(T,InsertPos); > + return T; > + } > + > + TreeTy* Create(TreeTy* L, TreeTy* OldTree, TreeTy* R) { > + assert (!isEmpty(OldTree)); > + > + if (OldTree->isMutable()) { > + OldTree->setLeft(L); > + OldTree->setRight(R); > + OldTree->setHeight(IncrementHeight(L,R)); > + return OldTree; > + } > + else return Create(L, Value(OldTree), R); > + } > + > + /// Balance - Used by Add_internal and Remove_internal to > + /// balance a newly created tree. > + TreeTy* Balance(TreeTy* L, value_type_ref V, TreeTy* R) { > + > + unsigned hl = Height(L); > + unsigned hr = Height(R); > + > + if (hl > hr + 2) { > + assert (!isEmpty(L) && > + "Left tree cannot be empty to have a height >= 2."); > + > + TreeTy* LL = Left(L); > + TreeTy* LR = Right(L); > + > + if (Height(LL) >= Height(LR)) > + return Create(LL, L, Create(LR,V,R)); > + > + assert (!isEmpty(LR) && > + "LR cannot be empty because it has a height >= 1."); > + > + TreeTy* LRL = Left(LR); > + TreeTy* LRR = Right(LR); > + > + return Create(Create(LL,L,LRL), LR, Create(LRR,V,R)); > + } > + else if (hr > hl + 2) { > + assert (!isEmpty(R) && > + "Right tree cannot be empty to have a height >= 2."); > + > + TreeTy* RL = Left(R); > + TreeTy* RR = Right(R); > + > + if (Height(RR) >= Height(RL)) > + return Create(Create(L,V,RL), R, RR); > + > + assert (!isEmpty(RL) && > + "RL cannot be empty because it has a height >= 1."); > + > + TreeTy* RLL = Left(RL); > + TreeTy* RLR = Right(RL); > + > + return Create(Create(L,V,RLL), RL, Create(RLR,R,RR)); > + } > + else > + return Create(L,V,R); > + } > + > + /// Add_internal - Creates a new tree that includes the specified > + /// data and the data from the original tree. If the original > tree > + /// already contained the data item, the original tree is > returned. > + TreeTy* Add_internal(value_type_ref V, TreeTy* T) { > + if (isEmpty(T)) > + return Create(T, V, T); > + > + assert (!T->isMutable()); > + > + key_type_ref K = ImutInfo::KeyOfValue(V); > + key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T)); > + > + if (ImutInfo::isEqual(K,KCurrent)) > + return Create(Left(T), V, Right(T)); > + else if (ImutInfo::isLess(K,KCurrent)) > + return Balance(Add_internal(V,Left(T)), Value(T), Right(T)); > + else > + return Balance(Left(T), Value(T), Add_internal(V,Right(T))); > + } > + > + /// Remove_interal - Creates a new tree that includes all the data > + /// from the original tree except the specified data. If the > + /// specified data did not exist in the original tree, the > original > + /// tree is returned. > + TreeTy* Remove_internal(key_type_ref K, TreeTy* T) { > + if (isEmpty(T)) > + return T; > + > + assert (!T->isMutable()); > + > + key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T)); > + > + if (ImutInfo::isEqual(K,KCurrent)) > + return CombineLeftRightTrees(Left(T),Right(T)); > + else if (ImutInfo::isLess(K,KCurrent)) > + return Balance(Remove_internal(K,Left(T)), Value(T), Right(T)); > + else > + return Balance(Left(T), Value(T), Remove_internal(K,Right(T))); > + } > + > + TreeTy* CombineLeftRightTrees(TreeTy* L, TreeTy* R) { > + if (isEmpty(L)) return R; > + if (isEmpty(R)) return L; > + > + TreeTy* OldNode; > + TreeTy* NewRight = RemoveMinBinding(R,OldNode); > + return Balance(L,Value(OldNode),NewRight); > + } > + > + TreeTy* RemoveMinBinding(TreeTy* T, TreeTy*& NodeRemoved) { > + assert (!isEmpty(T)); > + > + if (isEmpty(Left(T))) { > + NodeRemoved = T; > + return Right(T); > + } > + > + return Balance(RemoveMinBinding(Left(T),NodeRemoved),Value > (T),Right(T)); > + } > + > + /// MarkImmutable - Clears the mutable bits of a root and all of > its > + /// descendants. > + void MarkImmutable(TreeTy* T) { > + if (!T || !T->isMutable()) > + return; > + > + T->RemoveMutableFlag(); > + MarkImmutable(Left(T)); > + MarkImmutable(Right(T)); > + } > +}; > + > + > +// > ===------------------------------------------------------------------- > ---===// > +// Trait classes for Profile information. > +// > ===------------------------------------------------------------------- > ---===// > + > +/// Generic profile template. The default behavior is to invoke the > +/// profile method of an object. Specializations for primitive > integers > +/// and generic handling of pointers is done below. > +template > +struct ImutProfileInfo { > + typedef const T value_type; > + typedef const T& value_type_ref; > + > + static inline void Profile(FoldingSetNodeID& ID, value_type_ref > X) { > + X.Profile(ID); > + } > +}; > + > +/// Profile traits for integers. > +template > +struct ImutProfileInteger { > + typedef const T value_type; > + typedef const T& value_type_ref; > + > + static inline void Profile(FoldingSetNodeID& ID, value_type_ref > X) { > + ID.AddInteger(X); > + } > +}; > + > +#define PROFILE_INTEGER_INFO(X)\ > +template<> struct ImutProfileInfo : ImutProfileInteger {}; > + > +PROFILE_INTEGER_INFO(char) > +PROFILE_INTEGER_INFO(unsigned char) > +PROFILE_INTEGER_INFO(short) > +PROFILE_INTEGER_INFO(unsigned short) > +PROFILE_INTEGER_INFO(unsigned) > +PROFILE_INTEGER_INFO(signed) > +PROFILE_INTEGER_INFO(long) > +PROFILE_INTEGER_INFO(unsigned long) > +PROFILE_INTEGER_INFO(long long) > +PROFILE_INTEGER_INFO(unsigned long long) > + > +#undef PROFILE_INTEGER_INFO > + > +/// Generic profile trait for pointer types. We treat pointers as > +/// references to unique objects. > +template > +struct ImutProfileInfo { > + typedef const T* value_type; > + typedef value_type value_type_ref; > + > + static inline void Profile(FoldingSetNodeID &ID, value_type_ref > X) { > + ID.AddPointer(X); > + } > +}; > + > +// > ===------------------------------------------------------------------- > ---===// > +// Trait classes that contain element comparison operators and type > +// definitions used by ImutAVLTree, ImmutableSet, and > ImmutableMap. These > +// inherit from the profile traits (ImutProfileInfo) to include > operations > +// for element profiling. > +// > ===------------------------------------------------------------------- > ---===// > + > + > +/// ImutContainerInfo - Generic definition of comparison > operations for > +/// elements of immutable containers that defaults to using > +/// std::equal_to<> and std::less<> to perform comparison of > elements. > +template > +struct ImutContainerInfo : public ImutProfileInfo { > + typedef typename ImutProfileInfo::value_type value_type; > + typedef typename ImutProfileInfo::value_type_ref > value_type_ref; > + typedef value_type key_type; > + typedef value_type_ref key_type_ref; > + > + static inline key_type_ref KeyOfValue(value_type_ref D) { return > D; } > + > + static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) { > + return std::equal_to()(LHS,RHS); > + } > + > + static inline bool isLess(key_type_ref LHS, key_type_ref RHS) { > + return std::less()(LHS,RHS); > + } > +}; > + > +/// ImutContainerInfo - Specialization for pointer values to treat > pointers > +/// as references to unique objects. Pointers are thus compared by > +/// their addresses. > +template > +struct ImutContainerInfo : public ImutProfileInfo { > + typedef typename ImutProfileInfo::value_type value_type; > + typedef typename ImutProfileInfo::value_type_ref > value_type_ref; > + typedef value_type key_type; > + typedef value_type_ref key_type_ref; > + > + static inline key_type_ref KeyOfValue(value_type_ref D) { return > D; } > + > + static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) { > + return LHS == RHS; > + } > + > + static inline bool isLess(key_type_ref LHS, key_type_ref RHS) { > + return LHS < RHS; > + } > +}; > + > +// > ===------------------------------------------------------------------- > ---===// > +// Immutable Set > +// > ===------------------------------------------------------------------- > ---===// > + > +template > > +class ImmutableSet { > +public: > + typedef typename ValInfo::value_type value_type; > + typedef typename ValInfo::value_type_ref value_type_ref; > + > +private: > + typedef ImutAVLTree TreeTy; > + TreeTy* Root; > + > + ImmutableSet(TreeTy* R) : Root(R) {} > + > +public: > + > + class Factory { > + typename TreeTy::Factory F; > + > + public: > + Factory() {} > + > + ImmutableSet GetEmptySet() { return ImmutableSet(F.GetEmptyTree > ()); } > + > + ImmutableSet Add(ImmutableSet Old, value_type_ref V) { > + return ImmutableSet(F.Add(Old.Root,V)); > + } > + > + ImmutableSet Remove(ImmutableSet Old, value_type_ref V) { > + return ImmutableSet(F.Remove(Old.Root,V)); > + } > + > + private: > + Factory(const Factory& RHS) {}; > + void operator=(const Factory& RHS) {}; > + }; > + > + friend class Factory; > + > + bool contains(const value_type_ref V) const { > + return Root ? Root->contains(V) : false; > + } > + > + bool operator==(ImmutableSet RHS) const { > + return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == > RHS.Root; > + } > + > + bool operator!=(ImmutableSet RHS) const { > + return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root ! > = RHS.Root; > + } > + > + bool isEmpty() const { return !Root; } > + > + template > + void foreach(Callback& C) { if (Root) Root->foreach(C); } > + > + template > + void foreach() { if (Root) { Callback C; Root->foreach(C); } } > + > + //===--------------------------------------------------===// > + // For testing. > + //===--------------------------------------------------===// > + > + void verify() const { if (Root) Root->verify(); } > + unsigned getHeight() const { return Root ? Root->getHeight() : 0; } > +}; > + > +} // end namespace llvm > + > +#endif > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From kremenek at apple.com Tue Oct 9 17:55:14 2007 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 9 Oct 2007 15:55:14 -0700 Subject: [llvm-commits] [llvm] r42813 - in /llvm/trunk/include/llvm/ADT: ImmutableMap.h ImmutableSet.h In-Reply-To: <8DF233DB-923F-4E52-9919-F26050BE437A@apple.com> References: <200710092138.l99Lc9tX007438@zion.cs.uiuc.edu> <8DF233DB-923F-4E52-9919-F26050BE437A@apple.com> Message-ID: On Oct 9, 2007, at 3:04 PM, Tanya Lattner wrote: > > On Oct 9, 2007, at 2:38 PM, Ted Kremenek wrote: > >> Author: kremenek >> Date: Tue Oct 9 16:38:09 2007 >> New Revision: 42813 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=42813&view=rev >> Log: >> Added implementation of immutable (functional) maps and sets, as >> implemented on top of a functional AVL tree. The AVL balancing code >> is inspired by the OCaml implementation of Map, which also uses a >> functional >> AVL tree. >> >> Documentation is currently limited and cleanups are planned, but >> this code >> compiles and has been tested. >> > > You mention that documentation is limited, so this may be a stupid > question. Do you plan to add doxygen style comments to each function > providing a brief description of it? > > Thanks, > Tanya Yes I do plan on adding doxygen comments. The focus will be on documenting the public interface first. The internal implementation is still being cleaned up. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071009/d7becf22/attachment.html From evan.cheng at apple.com Tue Oct 9 18:36:27 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 09 Oct 2007 23:36:27 -0000 Subject: [llvm-commits] [llvm] r42820 - /llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Message-ID: <200710092336.l99NaRd5012629@zion.cs.uiuc.edu> Author: evancheng Date: Tue Oct 9 18:36:27 2007 New Revision: 42820 URL: http://llvm.org/viewvc/llvm-project?rev=42820&view=rev Log: Fix an extremely stupid bug that prevented first round of coalescing (physical registers only) from happening. Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=42820&r1=42819&r2=42820&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Tue Oct 9 18:36:27 2007 @@ -861,7 +861,8 @@ unsigned SrcReg, DstReg; if (!tii_->isMoveInstr(*Inst, SrcReg, DstReg)) continue; - if (TryAgain && !JoinCopy(Inst, SrcReg, DstReg, PhysOnly)) + bool Success = JoinCopy(Inst, SrcReg, DstReg, PhysOnly); + if (TryAgain && !Success) TryAgain->push_back(getCopyRec(Inst, SrcReg, DstReg)); } } From evan.cheng at apple.com Tue Oct 9 19:11:41 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 10 Oct 2007 00:11:41 -0000 Subject: [llvm-commits] [llvm] r42821 - /llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Message-ID: <200710100011.l9A0Bf6U014159@zion.cs.uiuc.edu> Author: evancheng Date: Tue Oct 9 19:11:40 2007 New Revision: 42821 URL: http://llvm.org/viewvc/llvm-project?rev=42821&view=rev Log: Bad choice of variable name. Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=42821&r1=42820&r2=42821&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Tue Oct 9 19:11:40 2007 @@ -861,8 +861,8 @@ unsigned SrcReg, DstReg; if (!tii_->isMoveInstr(*Inst, SrcReg, DstReg)) continue; - bool Success = JoinCopy(Inst, SrcReg, DstReg, PhysOnly); - if (TryAgain && !Success) + bool Done = JoinCopy(Inst, SrcReg, DstReg, PhysOnly); + if (TryAgain && !Done) TryAgain->push_back(getCopyRec(Inst, SrcReg, DstReg)); } } From dalej at apple.com Tue Oct 9 20:01:31 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 10 Oct 2007 01:01:31 -0000 Subject: [llvm-commits] [llvm] r42822 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Target/PowerPC/PPCISelLowering.cpp lib/Target/PowerPC/PPCISelLowering.h lib/Target/PowerPC/PPCInstrFormats.td lib/Target/PowerPC/PPCInstrInfo.td Message-ID: <200710100101.l9A11Wo2016469@zion.cs.uiuc.edu> Author: johannes Date: Tue Oct 9 20:01:31 2007 New Revision: 42822 URL: http://llvm.org/viewvc/llvm-project?rev=42822&view=rev Log: Next PPC long double bits: ppcf128->i32 conversion. Surprisingly complicated. Adds getTargetNode for 2 outputs, no inputs (missing). Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=42822&r1=42821&r2=42822&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue Oct 9 20:01:31 2007 @@ -403,6 +403,8 @@ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT, const SDOperand *Ops, unsigned NumOps); SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, + MVT::ValueType VT2); + SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, MVT::ValueType VT2, SDOperand Op1); SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, MVT::ValueType VT2, SDOperand Op1, SDOperand Op2); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=42822&r1=42821&r2=42822&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Oct 9 20:01:31 2007 @@ -3324,10 +3324,18 @@ case Expand: { // Convert f32 / f64 to i32 / i64. MVT::ValueType VT = Op.getValueType(); + MVT::ValueType OVT = Node->getOperand(0).getValueType(); + if (OVT == MVT::ppcf128 && VT == MVT::i32) { + Result = DAG.getNode(ISD::FP_TO_SINT, VT, + DAG.getNode(ISD::FP_ROUND, MVT::f64, + (DAG.getNode(ISD::FP_ROUND_INREG, + MVT::ppcf128, Node->getOperand(0), + DAG.getValueType(MVT::f64))))); + break; + } RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; switch (Node->getOpcode()) { case ISD::FP_TO_SINT: { - MVT::ValueType OVT = Node->getOperand(0).getValueType(); if (OVT == MVT::f32) LC = (VT == MVT::i32) ? RTLIB::FPTOSINT_F32_I32 : RTLIB::FPTOSINT_F32_I64; @@ -3345,7 +3353,6 @@ break; } case ISD::FP_TO_UINT: { - MVT::ValueType OVT = Node->getOperand(0).getValueType(); if (OVT == MVT::f32) LC = (VT == MVT::i32) ? RTLIB::FPTOUINT_F32_I32 : RTLIB::FPTOSINT_F32_I64; @@ -5159,6 +5166,17 @@ switch (Node->getOpcode()) { case ISD::CopyFromReg: assert(0 && "CopyFromReg must be legal!"); + case ISD::FP_ROUND_INREG: + if (VT == MVT::ppcf128 && + TLI.getOperationAction(ISD::FP_ROUND_INREG, VT) == + TargetLowering::Custom) { + SDOperand Result = TLI.LowerOperation(Op, DAG); + assert(Result.Val->getOpcode() == ISD::BUILD_PAIR); + Lo = Result.Val->getOperand(0); + Hi = Result.Val->getOperand(1); + break; + } + // fall through default: #ifndef NDEBUG cerr << "NODE: "; Node->dump(&DAG); cerr << "\n"; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=42822&r1=42821&r2=42822&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Oct 9 20:01:31 2007 @@ -3033,6 +3033,12 @@ return getNode(ISD::BUILTIN_OP_END+Opcode, VT, Ops, NumOps).Val; } SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT1, + MVT::ValueType VT2) { + const MVT::ValueType *VTs = getNodeValueTypes(VT1, VT2); + SDOperand Op; + return getNode(ISD::BUILTIN_OP_END+Opcode, VTs, 2, &Op, 0).Val; +} +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT1, MVT::ValueType VT2, SDOperand Op1) { const MVT::ValueType *VTs = getNodeValueTypes(VT1, VT2); return getNode(ISD::BUILTIN_OP_END+Opcode, VTs, 2, &Op1, 1).Val; Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=42822&r1=42821&r2=42822&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Tue Oct 9 20:01:31 2007 @@ -76,6 +76,9 @@ // Shortening conversions involving ppcf128 get expanded (2 regs -> 1 reg) setConvertAction(MVT::ppcf128, MVT::f64, Expand); setConvertAction(MVT::ppcf128, MVT::f32, Expand); + // This is used in the ppcf128->int sequence. Note it has different semantics + // from FP_ROUND: that rounds to nearest, this rounds to zero. + setOperationAction(ISD::FP_ROUND_INREG, MVT::ppcf128, Custom); // PowerPC has no intrinsics for these particular operations setOperationAction(ISD::MEMMOVE, MVT::Other, Expand); @@ -2079,6 +2082,64 @@ return Bits; } +static SDOperand LowerFP_ROUND_INREG(SDOperand Op, SelectionDAG &DAG) { + assert(Op.getValueType() == MVT::ppcf128); + SDNode *Node = Op.Val; + assert(Node->getOperand(0).getValueType() == MVT::ppcf128); + assert(Node->getOperand(0).Val->getOpcode()==ISD::BUILD_PAIR); + SDOperand Lo = Node->getOperand(0).Val->getOperand(0); + SDOperand Hi = Node->getOperand(0).Val->getOperand(1); + + // This sequence changes FPSCR to do round-to-zero, adds the two halves + // of the long double, and puts FPSCR back the way it was. We do not + // actually model FPSCR. + std::vector NodeTys; + SDOperand Ops[4], Result, MFFSreg, InFlag, FPreg; + + NodeTys.push_back(MVT::f64); // Return register + NodeTys.push_back(MVT::Flag); // Returns a flag for later insns + Result = DAG.getNode(PPCISD::MFFS, NodeTys, &InFlag, 0); + MFFSreg = Result.getValue(0); + InFlag = Result.getValue(1); + + NodeTys.clear(); + NodeTys.push_back(MVT::Flag); // Returns a flag + Ops[0] = DAG.getConstant(31, MVT::i32); + Ops[1] = InFlag; + Result = DAG.getNode(PPCISD::MTFSB1, NodeTys, Ops, 2); + InFlag = Result.getValue(0); + + NodeTys.clear(); + NodeTys.push_back(MVT::Flag); // Returns a flag + Ops[0] = DAG.getConstant(30, MVT::i32); + Ops[1] = InFlag; + Result = DAG.getNode(PPCISD::MTFSB0, NodeTys, Ops, 2); + InFlag = Result.getValue(0); + + NodeTys.clear(); + NodeTys.push_back(MVT::f64); // result of add + NodeTys.push_back(MVT::Flag); // Returns a flag + Ops[0] = Lo; + Ops[1] = Hi; + Ops[2] = InFlag; + Result = DAG.getNode(PPCISD::FADDRTZ, NodeTys, Ops, 3); + FPreg = Result.getValue(0); + InFlag = Result.getValue(1); + + NodeTys.clear(); + NodeTys.push_back(MVT::f64); + Ops[0] = DAG.getConstant(1, MVT::i32); + Ops[1] = MFFSreg; + Ops[2] = FPreg; + Ops[3] = InFlag; + Result = DAG.getNode(PPCISD::MTFSF, NodeTys, Ops, 4); + FPreg = Result.getValue(0); + + // We know the low half is about to be thrown away, so just use something + // convenient. + return DAG.getNode(ISD::BUILD_PAIR, Lo.getValueType(), FPreg, FPreg); +} + static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) { if (Op.getOperand(0).getValueType() == MVT::i64) { SDOperand Bits = DAG.getNode(ISD::BIT_CONVERT, MVT::f64, Op.getOperand(0)); @@ -2935,6 +2996,7 @@ case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG); case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG); + case ISD::FP_ROUND_INREG: return LowerFP_ROUND_INREG(Op, DAG); // Lower 64-bit shifts. case ISD::SHL_PARTS: return LowerSHL_PARTS(Op, DAG); Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=42822&r1=42821&r2=42822&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h Tue Oct 9 20:01:31 2007 @@ -129,7 +129,28 @@ /// byte-swapping load instruction. It loads "Type" bits, byte swaps it, /// then puts it in the bottom bits of the GPRC. TYPE can be either i16 /// or i32. - LBRX + LBRX, + + // The following 5 instructions are used only as part of the + // long double-to-int conversion sequence. + + /// OUTFLAG = MFFS F8RC - This moves the FPSCR (not modelled) into the + /// register. + MFFS, + + /// OUTFLAG = MTFSB0 INFLAG - This clears a bit in the FPSCR. + MTFSB0, + + /// OUTFLAG = MTFSB1 INFLAG - This sets a bit in the FPSCR. + MTFSB1, + + /// F8RC, OUTFLAG = FADDRTZ F8RC, F8RC, INFLAG - This is an FADD done with + /// rounding towards zero. It has flags added so it won't move past the + /// FPSCR-setting instructions. + FADDRTZ, + + /// MTFSF = F8RC, INFLAG - This moves the register into the FPSCR. + MTFSF }; } Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td?rev=42822&r1=42821&r2=42822&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td Tue Oct 9 20:01:31 2007 @@ -315,6 +315,34 @@ : XForm_base_r3xo { } +// This is used for MFFS, MTFSB0, MTFSB1. 42 is arbitrary; this series of +// numbers presumably relates to some document, but I haven't found it. +class XForm_42 opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : XForm_base_r3xo { + let Pattern = pattern; + + bit RC = 0; // set by isDOT + + let Inst{6-10} = RST; + let Inst{11-20} = 0; + let Inst{21-30} = xo; + let Inst{31} = RC; +} +class XForm_43 opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : XForm_base_r3xo { + let Pattern = pattern; + bits<5> FM; + + bit RC = 0; // set by isDOT + + let Inst{6-10} = FM; + let Inst{11-20} = 0; + let Inst{21-30} = xo; + let Inst{31} = RC; +} + // DCB_Form - Form X instruction, used for dcb* instructions. class DCB_Form xo, bits<5> immfield, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list pattern> @@ -513,6 +541,27 @@ let SPR = spr; } +// XFL-Form - MTFSF +// This is probably 1.7.9, but I don't have the reference that uses this +// numbering scheme... +class XFLForm opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, + string cstr, InstrItinClass itin, listpattern> + : I { + bits<8> FM; + bits<5> RT; + + bit RC = 0; // set by isDOT + let Pattern = pattern; + let Constraints = cstr; + + let Inst{6} = 0; + let Inst{7-14} = FM; + let Inst{15} = 0; + let Inst{16-20} = RT; + let Inst{21-30} = xo; + let Inst{31} = RC; +} + // 1.7.10 XS-Form - SRADI. class XSForm_1 opcode, bits<9> xo, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list pattern> Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=42822&r1=42821&r2=42822&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Tue Oct 9 20:01:31 2007 @@ -53,6 +53,21 @@ def PPCfctiwz : SDNode<"PPCISD::FCTIWZ", SDTFPUnaryOp, []>; def PPCstfiwx : SDNode<"PPCISD::STFIWX", SDT_PPCstfiwx, [SDNPHasChain]>; +// This sequence is used for long double->int conversions. It changes the +// bits in the FPSCR which is not modelled. +def PPCmffs : SDNode<"PPCISD::MFFS", SDTypeProfile<1, 0, [SDTCisVT<0, f64>]>, + [SDNPOutFlag]>; +def PPCmtfsb0 : SDNode<"PPCISD::MTFSB0", SDTypeProfile<0, 1, [SDTCisInt<0>]>, + [SDNPInFlag, SDNPOutFlag]>; +def PPCmtfsb1 : SDNode<"PPCISD::MTFSB1", SDTypeProfile<0, 1, [SDTCisInt<0>]>, + [SDNPInFlag, SDNPOutFlag]>; +def PPCfaddrtz: SDNode<"PPCISD::FADDRTZ", SDTFPBinOp, + [SDNPInFlag, SDNPOutFlag]>; +def PPCmtfsf : SDNode<"PPCISD::MTFSF", SDTypeProfile<1, 3, + [SDTCisVT<0, f64>, SDTCisInt<1>, SDTCisVT<2, f64>, + SDTCisVT<3, f64>]>, + [SDNPInFlag]>; + def PPCfsel : SDNode<"PPCISD::FSEL", // Type constraint for fsel. SDTypeProfile<1, 3, [SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, @@ -873,6 +888,37 @@ "mfcr $rT, $FXM", SprMFCR>, PPC970_DGroup_First, PPC970_Unit_CRU; +// Instructions to manipulate FPSCR. Only long double handling uses these. +// FPSCR is not modelled; we use the SDNode Flag to keep things in order. + +def MFFS : XForm_42<63, 583, (outs F8RC:$rT), (ins), + "mffs $rT", IntMFFS, + [(set F8RC:$rT, (PPCmffs))]>, + PPC970_DGroup_Single, PPC970_Unit_FPU; +def MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM), + "mtfsb0 $FM", IntMTFSB0, + [(PPCmtfsb0 (i32 imm:$FM))]>, + PPC970_DGroup_Single, PPC970_Unit_FPU; +def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM), + "mtfsb1 $FM", IntMTFSB0, + [(PPCmtfsb1 (i32 imm:$FM))]>, + PPC970_DGroup_Single, PPC970_Unit_FPU; +def FADDrtz: AForm_2<63, 21, + (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB), + "fadd $FRT, $FRA, $FRB", FPGeneral, + [(set F8RC:$FRT, (PPCfaddrtz F8RC:$FRA, F8RC:$FRB))]>, + PPC970_DGroup_Single, PPC970_Unit_FPU; +// MTFSF does not actually produce an FP result. We pretend it copies +// input reg B to the output. If we didn't do this it would look like the +// instruction had no outputs (because we aren't modelling the FPSCR) and +// it would be deleted. +def MTFSF : XFLForm<63, 711, (outs F8RC:$FRA), + (ins i32imm:$FM, F8RC:$rT, F8RC:$FRB), + "mtfsf $FM, $rT", "$FRB = $FRA", IntMTFSB0, + [(set F8RC:$FRA, (PPCmtfsf (i32 imm:$FM), + F8RC:$rT, F8RC:$FRB))]>, + PPC970_DGroup_Single, PPC970_Unit_FPU; + let PPC970_Unit = 1 in { // FXU Operations. // XO-Form instructions. Arithmetic instructions that can set overflow bit From isanbard at gmail.com Wed Oct 10 00:46:02 2007 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 10 Oct 2007 05:46:02 -0000 Subject: [llvm-commits] [llvm] r42823 - /llvm/trunk/include/llvm/Target/MRegisterInfo.h Message-ID: <200710100546.l9A5k3dg027081@zion.cs.uiuc.edu> Author: void Date: Wed Oct 10 00:45:59 2007 New Revision: 42823 URL: http://llvm.org/viewvc/llvm-project?rev=42823&view=rev Log: Fix 80-column violations Modified: llvm/trunk/include/llvm/Target/MRegisterInfo.h Modified: llvm/trunk/include/llvm/Target/MRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/MRegisterInfo.h?rev=42823&r1=42822&r2=42823&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/MRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/MRegisterInfo.h Wed Oct 10 00:45:59 2007 @@ -392,22 +392,22 @@ return get(RegNo).Name; } - /// getNumRegs - Return the number of registers this target has - /// (useful for sizing arrays holding per register information) + /// getNumRegs - Return the number of registers this target has (useful for + /// sizing arrays holding per register information) unsigned getNumRegs() const { return NumRegs; } - /// areAliases - Returns true if the two registers alias each other, - /// false otherwise + /// areAliases - Returns true if the two registers alias each other, false + /// otherwise bool areAliases(unsigned regA, unsigned regB) const { for (const unsigned *Alias = getAliasSet(regA); *Alias; ++Alias) if (*Alias == regB) return true; return false; } - /// regsOverlap - Returns true if the two registers are equal or alias - /// each other. The registers may be virtual register. + /// regsOverlap - Returns true if the two registers are equal or alias each + /// other. The registers may be virtual register. bool regsOverlap(unsigned regA, unsigned regB) const { if (regA == regB) return true; @@ -447,9 +447,9 @@ const MachineFunction *MF) const =0; /// getReservedRegs - Returns a bitset indexed by physical register number - /// indicating if a register is a special register that has particular uses and - /// should be considered unavailable at all times, e.g. SP, RA. This is used by - /// register scavenger to determine what registers are free. + /// indicating if a register is a special register that has particular uses + /// and should be considered unavailable at all times, e.g. SP, RA. This is + /// used by register scavenger to determine what registers are free. virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0; /// getSubReg - Returns the physical register number of sub-register "Index" @@ -482,10 +482,10 @@ // immediates and memory. FIXME: Move these to TargetInstrInfo.h. // - /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved - /// registers and returns true if it isn't possible / profitable to do so by - /// issuing a series of store instructions via storeRegToStackSlot(). Returns - /// false otherwise. + /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee + /// saved registers and returns true if it isn't possible / profitable to do + /// so by issuing a series of store instructions via + /// storeRegToStackSlot(). Returns false otherwise. virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector &CSI) const { @@ -543,12 +543,11 @@ unsigned DestReg, const MachineInstr *Orig) const = 0; - /// foldMemoryOperand - Attempt to fold a load or store of the - /// specified stack slot into the specified machine instruction for - /// the specified operand. If this is possible, a new instruction - /// is returned with the specified operand folded, otherwise NULL is - /// returned. The client is responsible for removing the old - /// instruction and adding the new one in the instruction stream + /// foldMemoryOperand - Attempt to fold a load or store of the specified stack + /// slot into the specified machine instruction for the specified operand. If + /// this is possible, a new instruction is returned with the specified operand + /// folded, otherwise NULL is returned. The client is responsible for removing + /// the old instruction and adding the new one in the instruction stream virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, int FrameIndex) const { @@ -564,12 +563,12 @@ return 0; } - /// unfoldMemoryOperand - Separate a single instruction which folded a load or a - /// a store or a load and a store into two or more instruction. If this is + /// unfoldMemoryOperand - Separate a single instruction which folded a load or + /// a a store or a load and a store into two or more instruction. If this is /// possible, returns true as well as the new instructions by reference. virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, SSARegMap *RegMap, - SmallVector &NewMIs) const { + SmallVector &NewMIs) const{ return false; } @@ -578,21 +577,22 @@ return false; } - /// targetHandlesStackFrameRounding - Returns true if the target is responsible - /// for rounding up the stack frame (probably at emitPrologue time). + /// targetHandlesStackFrameRounding - Returns true if the target is + /// responsible for rounding up the stack frame (probably at emitPrologue + /// time). virtual bool targetHandlesStackFrameRounding() const { return false; } - /// requiresRegisterScavenging - returns true if the target requires (and - /// can make use of) the register scavenger. + /// requiresRegisterScavenging - returns true if the target requires (and can + /// make use of) the register scavenger. virtual bool requiresRegisterScavenging(const MachineFunction &MF) const { return false; } - /// hasFP - Return true if the specified function should have a dedicated frame - /// pointer register. For most targets this is true only if the function has - /// variable sized allocas or if frame pointer elimination is disabled. + /// hasFP - Return true if the specified function should have a dedicated + /// frame pointer register. For most targets this is true only if the function + /// has variable sized allocas or if frame pointer elimination is disabled. virtual bool hasFP(const MachineFunction &MF) const = 0; // hasReservedCallFrame - Under normal circumstances, when a frame pointer is From evan.cheng at apple.com Wed Oct 10 02:19:15 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 10 Oct 2007 00:19:15 -0700 Subject: [llvm-commits] [llvm] r42822 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Target/PowerPC/PPCISelLowering.cpp lib/Target/PowerPC/PPCISelLowering.h lib/Target/PowerPC/PPCInstrFormats.td lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: <200710100101.l9A11Wo2016469@zion.cs.uiuc.edu> References: <200710100101.l9A11Wo2016469@zion.cs.uiuc.edu> Message-ID: On Oct 9, 2007, at 6:01 PM, Dale Johannesen wrote: > > ====================================================================== > ======== > --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) > +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue Oct 9 > 20:01:31 2007 > @@ -403,6 +403,8 @@ > SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT, > const SDOperand *Ops, unsigned NumOps); > SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, > + MVT::ValueType VT2); > + SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, > MVT::ValueType VT2, SDOperand Op1); This seems unnecessary. You can use this variant: SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, MVT::ValueType VT2, const SDOperand *Ops, unsigned NumOps); > > +// Instructions to manipulate FPSCR. Only long double handling > uses these. > +// FPSCR is not modelled; we use the SDNode Flag to keep things in > order. > + > +def MFFS : XForm_42<63, 583, (outs F8RC:$rT), (ins), > + "mffs $rT", IntMFFS, > + [(set F8RC:$rT, (PPCmffs))]>, > + PPC970_DGroup_Single, PPC970_Unit_FPU; > +def MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM), > + "mtfsb0 $FM", IntMTFSB0, > + [(PPCmtfsb0 (i32 imm:$FM))]>, > + PPC970_DGroup_Single, PPC970_Unit_FPU; > +def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM), > + "mtfsb1 $FM", IntMTFSB0, > + [(PPCmtfsb1 (i32 imm:$FM))]>, > + PPC970_DGroup_Single, PPC970_Unit_FPU; > +def FADDrtz: AForm_2<63, 21, > + (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB), > + "fadd $FRT, $FRA, $FRB", FPGeneral, > + [(set F8RC:$FRT, (PPCfaddrtz F8RC:$FRA, F8RC: > $FRB))]>, > + PPC970_DGroup_Single, PPC970_Unit_FPU; > +// MTFSF does not actually produce an FP result. We pretend it > copies > +// input reg B to the output. If we didn't do this it would look > like the > +// instruction had no outputs (because we aren't modelling the > FPSCR) and > +// it would be deleted. > +def MTFSF : XFLForm<63, 711, (outs F8RC:$FRA), > + (ins i32imm:$FM, F8RC:$rT, F8RC:$FRB), > + "mtfsf $FM, $rT", "$FRB = $FRA", IntMTFSB0, > + [(set F8RC:$FRA, (PPCmtfsf (i32 imm:$FM), > + F8RC:$rT, F8RC: > $FRB))]>, > + PPC970_DGroup_Single, PPC970_Unit_FPU; Ewww. :-) It just occurred to me you might want to implement this lot with the usesCustomDAGSchedInserter = 1 hack. It allows you to expand a pseudo PPC FP_ROUND_INREG node into multiple MI's at the end of scheduling. It's also a hack but might be a little bit cleaner than this. Sorry it didn't come to me when we were talking about this. :-( Evan > + > let PPC970_Unit = 1 in { // FXU Operations. > > // XO-Form instructions. Arithmetic instructions that can set > overflow bit > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Wed Oct 10 04:54:53 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 10 Oct 2007 09:54:53 -0000 Subject: [llvm-commits] [llvm] r42824 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200710100954.l9A9srNG009063@zion.cs.uiuc.edu> Author: baldrick Date: Wed Oct 10 04:54:50 2007 New Revision: 42824 URL: http://llvm.org/viewvc/llvm-project?rev=42824&view=rev Log: Correct swapped arguments to getConstant. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=42824&r1=42823&r2=42824&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Oct 10 04:54:50 2007 @@ -2068,7 +2068,7 @@ N0.Val->hasOneUse() && isSetCCEquivalent(N0.getOperand(0), LHS, RHS, CC)){ SDOperand V = N0.getOperand(0); V = DAG.getNode(ISD::XOR, V.getValueType(), V, - DAG.getConstant(V.getValueType(), 1)); + DAG.getConstant(1, V.getValueType())); AddToWorkList(V.Val); return DAG.getNode(ISD::ZERO_EXTEND, VT, V); } From djg at cray.com Wed Oct 10 09:36:15 2007 From: djg at cray.com (Dan Gohman) Date: Wed, 10 Oct 2007 09:36:15 -0500 Subject: [llvm-commits] RFC: internal label names Message-ID: <20071010143615.GR21991@village.us.cray.com> The attached patch changes the names of internal labels used by codegen. In place of the "function number", which is a number that codegen itself assigns specifically for this purpose, it uses the (mangled) name of the function, which is already sufficiently unique. For example, what currently looks like this: .LCPI1_3: where 1 is the function number and 3 is the constant index would look like this: .LCPI3_foo: Note that the constant index is now first, so the name can go last to avoid problems with names containing underscores. I saw this in another compiler and liked it. Does anyone here dislike it? Dan -- Dan Gohman, Cray Inc. -------------- next part -------------- Index: test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll =================================================================== --- test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll (revision 42821) +++ test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll (working copy) @@ -1,5 +1,5 @@ ; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86 | %prcontext je 1 | \ -; RUN: grep BB1_1: +; RUN: grep BB1_main: %str = internal constant [14 x sbyte] c"Hello world!\0A\00" ; <[14 x sbyte]*> [#uses=1] %str = internal constant [13 x sbyte] c"Blah world!\0A\00" ; <[13 x sbyte]*> [#uses=1] Index: test/CodeGen/X86/2007-01-08-InstrSched.ll =================================================================== --- test/CodeGen/X86/2007-01-08-InstrSched.ll (revision 42821) +++ test/CodeGen/X86/2007-01-08-InstrSched.ll (working copy) @@ -1,6 +1,6 @@ ; PR1075 ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | \ -; RUN: %prcontext {mulss LCPI1_3} 1 | grep mulss | count 1 +; RUN: %prcontext {mulss LCPI3__foo} 1 | grep mulss | count 1 define float @foo(float %x) { %tmp1 = mul float %x, 3.000000e+00 Index: test/CodeGen/X86/fp_constant_op.llx =================================================================== --- test/CodeGen/X86/fp_constant_op.llx (revision 42821) +++ test/CodeGen/X86/fp_constant_op.llx (working copy) @@ -3,32 +3,32 @@ ; Test that the load of the constant is folded into the operation. -double %test_add(double %P) { +double %foo_add(double %P) { %tmp.1 = add double %P, 0x405EC00000000000 ret double %tmp.1 } -double %test_mul(double %P) { +double %foo_mul(double %P) { %tmp.1 = mul double %P, 0x405EC00000000000 ret double %tmp.1 } -double %test_sub(double %P) { +double %foo_sub(double %P) { %tmp.1 = sub double %P, 0x405EC00000000000 ret double %tmp.1 } -double %test_subr(double %P) { +double %foo_subr(double %P) { %tmp.1 = sub double 0x405EC00000000000, %P ret double %tmp.1 } -double %test_div(double %P) { +double %foo_div(double %P) { %tmp.1 = div double %P, 0x405EC00000000000 ret double %tmp.1 } -double %test_divr(double %P) { +double %foo_divr(double %P) { %tmp.1 = div double 0x405EC00000000000, %P ret double %tmp.1 } Index: include/llvm/CodeGen/AsmPrinter.h =================================================================== --- include/llvm/CodeGen/AsmPrinter.h (revision 42821) +++ include/llvm/CodeGen/AsmPrinter.h (working copy) @@ -36,13 +36,6 @@ class AsmPrinter : public MachineFunctionPass { static char ID; - /// FunctionNumber - This provides a unique ID for each function emitted in - /// this translation unit. It is autoincremented by SetupMachineFunction, - /// and can be accessed with getFunctionNumber() and - /// IncrementFunctionNumber(). - /// - unsigned FunctionNumber; - protected: // Necessary for external weak linkage support std::set ExtWeakSymbols; @@ -160,15 +153,6 @@ /// is being processed from runOnMachineFunction. void SetupMachineFunction(MachineFunction &MF); - /// getFunctionNumber - Return a unique ID for the current function. - /// - unsigned getFunctionNumber() const { return FunctionNumber; } - - /// IncrementFunctionNumber - Increase Function Number. AsmPrinters should - /// not normally call this, as the counter is automatically bumped by - /// SetupMachineFunction. - void IncrementFunctionNumber() { FunctionNumber++; } - /// EmitConstantPool - Print to the current output stream assembly /// representations of the constants in the constant pool MCP. This is /// used to print out constants which have been "spilled to memory" by Index: lib/CodeGen/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter.cpp (revision 42821) +++ lib/CodeGen/AsmPrinter.cpp (working copy) @@ -35,7 +35,7 @@ char AsmPrinter::ID = 0; AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm, const TargetAsmInfo *T) - : MachineFunctionPass((intptr_t)&ID), FunctionNumber(0), O(o), TM(tm), TAI(T) + : MachineFunctionPass((intptr_t)&ID), O(o), TM(tm), TAI(T) {} std::string AsmPrinter::getSectionForFunction(const Function &F) const { @@ -169,7 +169,6 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { // What's my mangled name? CurrentFnName = Mang->getValueName(MF.getFunction()); - IncrementFunctionNumber(); } /// EmitConstantPool - Print to the current output stream assembly @@ -219,8 +218,9 @@ SwitchToDataSection(Section); EmitAlignment(Alignment); for (unsigned i = 0, e = CP.size(); i != e; ++i) { - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' - << CP[i].second << ":\t\t\t\t\t" << TAI->getCommentString() << " "; + O << TAI->getPrivateGlobalPrefix() << "CPI" << CP[i].second + << '_' << CurrentFnName + << ":\t\t\t\t\t" << TAI->getCommentString() << ' '; WriteTypeSymbolic(O, CP[i].first.getType(), 0) << '\n'; if (CP[i].first.isMachineConstantPoolEntry()) EmitMachineConstantPoolValue(CP[i].first.Val.MachineCPVal); @@ -293,10 +293,10 @@ // the assembler and linker the extents of the jump table object. The // second label is actually referenced by the code. if (const char *JTLabelPrefix = TAI->getJumpTableSpecialLabelPrefix()) - O << JTLabelPrefix << "JTI" << getFunctionNumber() << '_' << i << ":\n"; + O << JTLabelPrefix << "JTI" << i << '_' << CurrentFnName << ":\n"; - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << i << ":\n"; + O << TAI->getPrivateGlobalPrefix() << "JTI" << i + << '_' << CurrentFnName << ":\n"; for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { O << JTEntryDirective << ' '; @@ -306,15 +306,15 @@ // If we're emitting non-PIC code, then emit the entries as direct // references to the target basic blocks. if (!EmittedSets.empty()) { - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << '_' << i << "_set_" << JTBBs[ii]->getNumber(); + O << TAI->getPrivateGlobalPrefix() << i + << '_' << "_set_" << JTBBs[ii]->getNumber() << '_' << CurrentFnName; } else if (IsPic) { printBasicBlockLabel(JTBBs[ii], false, false); // If the arch uses custom Jump Table directives, don't calc relative to // JT if (!HadJTEntryDirective) O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" - << getFunctionNumber() << '_' << i; + << i << '_' << CurrentFnName; } else { printBasicBlockLabel(JTBBs[ii], false, false); } @@ -1209,8 +1209,8 @@ void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB, bool printColon, bool printComment) const { - O << TAI->getPrivateGlobalPrefix() << "BB" << getFunctionNumber() << "_" - << MBB->getNumber(); + O << TAI->getPrivateGlobalPrefix() << "BB" << MBB->getNumber() << '_' + << CurrentFnName; if (printColon) O << ':'; if (printComment && MBB->getBasicBlock()) @@ -1226,10 +1226,10 @@ return; O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() - << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','; + << uid << "_set_" << MBB->getNumber() << '_' << CurrentFnName << ','; printBasicBlockLabel(MBB, false, false); - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << uid << '\n'; + O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << uid + << '_' << CurrentFnName << '\n'; } void AsmPrinter::printSetLabel(unsigned uid, unsigned uid2, @@ -1238,11 +1238,11 @@ return; O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() - << getFunctionNumber() << '_' << uid << '_' << uid2 - << "_set_" << MBB->getNumber() << ','; + << uid << '_' << uid2 + << "_set_" << MBB->getNumber() << '_' << CurrentFnName << ','; printBasicBlockLabel(MBB, false, false); - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << uid << '_' << uid2 << '\n'; + O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << uid + << '_' << uid2 << '_' << CurrentFnName << '\n'; } /// printDataDirective - This method prints the asm directive for the Index: lib/Target/Alpha/AlphaAsmPrinter.cpp =================================================================== --- lib/Target/Alpha/AlphaAsmPrinter.cpp (revision 42821) +++ lib/Target/Alpha/AlphaAsmPrinter.cpp (working copy) @@ -104,8 +104,8 @@ return; case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" - << MO.getConstantPoolIndex(); + O << TAI->getPrivateGlobalPrefix() << "CPI" << MO.getConstantPoolIndex() + << '_' << CurrentFnName; return; case MachineOperand::MO_ExternalSymbol: @@ -121,8 +121,8 @@ } case MachineOperand::MO_JumpTableIndex: - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << MO.getJumpTableIndex(); + O << TAI->getPrivateGlobalPrefix() << "JTI" << MO.getJumpTableIndex() + << '_' << CurrentFnName; return; default: Index: lib/Target/ARM/ARMAsmPrinter.cpp =================================================================== --- lib/Target/ARM/ARMAsmPrinter.cpp (revision 42821) +++ lib/Target/ARM/ARMAsmPrinter.cpp (working copy) @@ -319,12 +319,12 @@ break; } case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() - << '_' << MO.getConstantPoolIndex(); + O << TAI->getPrivateGlobalPrefix() << "CPI" << MO.getConstantPoolIndex() + << '_' << CurrentFnName; break; case MachineOperand::MO_JumpTableIndex: - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << MO.getJumpTableIndex(); + O << TAI->getPrivateGlobalPrefix() << "JTI" << MO.getJumpTableIndex() + << '_' << CurrentFnName; break; default: O << ""; abort (); break; @@ -652,8 +652,8 @@ // data itself. if (!strcmp(Modifier, "label")) { unsigned ID = MI->getOperand(OpNo).getImm(); - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() - << '_' << ID << ":\n"; + O << TAI->getPrivateGlobalPrefix() << "CPI" << ID + << '_' << CurrentFnName << ":\n"; } else { assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE"); unsigned CPI = MI->getOperand(OpNo).getConstantPoolIndex(); @@ -677,8 +677,8 @@ const MachineOperand &MO1 = MI->getOperand(OpNo); const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id unsigned JTI = MO1.getJumpTableIndex(); - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << JTI << '_' << MO2.getImmedValue() << ":\n"; + O << TAI->getPrivateGlobalPrefix() << "JTI" << JTI + << '_' << MO2.getImmedValue() << '_' << CurrentFnName << ":\n"; const char *JTEntryDirective = TAI->getJumpTableDirective(); if (!JTEntryDirective) @@ -697,15 +697,16 @@ O << JTEntryDirective << ' '; if (UseSet) - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << '_' << JTI << '_' << MO2.getImmedValue() - << "_set_" << MBB->getNumber(); + O << TAI->getPrivateGlobalPrefix() << JTI + << '_' << MO2.getImmedValue() + << "_set_" << MBB->getNumber() + << CurrentFnName; else if (TM.getRelocationModel() == Reloc::PIC_) { printBasicBlockLabel(MBB, false, false); // If the arch uses custom Jump Table directives, don't calc relative to JT if (!TAI->getJumpTableDirective()) O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" - << getFunctionNumber() << '_' << JTI << '_' << MO2.getImmedValue(); + << JTI << '_' << MO2.getImmedValue() << '_' << CurrentFnName; } else printBasicBlockLabel(MBB, false, false); if (i != e-1) Index: lib/Target/IA64/IA64AsmPrinter.cpp =================================================================== --- lib/Target/IA64/IA64AsmPrinter.cpp (revision 42821) +++ lib/Target/IA64/IA64AsmPrinter.cpp (working copy) @@ -179,8 +179,8 @@ return; case MachineOperand::MO_ConstantPoolIndex: { O << "@gprel(" << TAI->getPrivateGlobalPrefix() - << "CPI" << getFunctionNumber() << "_" - << MO.getConstantPoolIndex() << ")"; + << "CPI" << MO.getConstantPoolIndex() << '_' + << CurrentFnName << ")"; return; } Index: lib/Target/Mips/MipsAsmPrinter.cpp =================================================================== --- lib/Target/Mips/MipsAsmPrinter.cpp (revision 42821) +++ lib/Target/Mips/MipsAsmPrinter.cpp (working copy) @@ -363,7 +363,7 @@ case MachineOperand::MO_ConstantPoolIndex: O << TAI->getPrivateGlobalPrefix() << "CPI" - << getFunctionNumber() << "_" << MO.getConstantPoolIndex(); + << MO.getConstantPoolIndex() << '_' << CurrentFnName; break; default: Index: lib/Target/PowerPC/PPCAsmPrinter.cpp =================================================================== --- lib/Target/PowerPC/PPCAsmPrinter.cpp (revision 42821) +++ lib/Target/PowerPC/PPCAsmPrinter.cpp (working copy) @@ -164,7 +164,7 @@ O << "lo16("; printOp(MI->getOperand(OpNo)); if (TM.getRelocationModel() == Reloc::PIC_) - O << "-\"L" << getFunctionNumber() << "$pb\")"; + O << "-\"L" "pb$" << CurrentFnName << "\")"; else O << ')'; } @@ -208,8 +208,8 @@ O << (int)MI->getOperand(OpNo).getImmedValue()*4; } void printPICLabel(const MachineInstr *MI, unsigned OpNo) { - O << "\"L" << getFunctionNumber() << "$pb\"\n"; - O << "\"L" << getFunctionNumber() << "$pb\":"; + O << "\"L" "pb$" << CurrentFnName << "\"\n"; + O << "\"L" "pb$" << CurrentFnName << "\":"; } void printSymbolHi(const MachineInstr *MI, unsigned OpNo) { if (MI->getOperand(OpNo).isImmediate()) { @@ -218,7 +218,7 @@ if (Subtarget.isDarwin()) O << "ha16("; printOp(MI->getOperand(OpNo)); if (TM.getRelocationModel() == Reloc::PIC_) - O << "-\"L" << getFunctionNumber() << "$pb\""; + O << "-\"L" "pb$" << CurrentFnName << "\""; if (Subtarget.isDarwin()) O << ')'; else @@ -232,7 +232,7 @@ if (Subtarget.isDarwin()) O << "lo16("; printOp(MI->getOperand(OpNo)); if (TM.getRelocationModel() == Reloc::PIC_) - O << "-\"L" << getFunctionNumber() << "$pb\""; + O << "-\"L" "pb$" << CurrentFnName << "\""; if (Subtarget.isDarwin()) O << ')'; else @@ -362,13 +362,13 @@ printBasicBlockLabel(MO.getMachineBasicBlock()); return; case MachineOperand::MO_JumpTableIndex: - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << MO.getJumpTableIndex(); + O << TAI->getPrivateGlobalPrefix() << "JTI" << MO.getJumpTableIndex() + << '_' << CurrentFnName; // FIXME: PIC relocation model return; case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() - << '_' << MO.getConstantPoolIndex(); + O << TAI->getPrivateGlobalPrefix() << "CPI" << MO.getConstantPoolIndex() + << '_' << CurrentFnName; return; case MachineOperand::MO_ExternalSymbol: // Computing the address of an external symbol, not calling it. Index: lib/Target/Sparc/SparcAsmPrinter.cpp =================================================================== --- lib/Target/Sparc/SparcAsmPrinter.cpp (revision 42821) +++ lib/Target/Sparc/SparcAsmPrinter.cpp (working copy) @@ -164,8 +164,8 @@ O << MO.getSymbolName(); break; case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" - << MO.getConstantPoolIndex(); + O << TAI->getPrivateGlobalPrefix() << "CPI" << MO.getConstantPoolIndex() + << '_' << CurrentFnName; break; default: O << ""; abort (); break; Index: lib/Target/X86/X86ATTAsmPrinter.cpp =================================================================== --- lib/Target/X86/X86ATTAsmPrinter.cpp (revision 42821) +++ lib/Target/X86/X86ATTAsmPrinter.cpp (working copy) @@ -31,14 +31,14 @@ STATISTIC(EmittedInsts, "Number of machine instrs printed"); -static std::string computePICLabel(unsigned FnNum, +static std::string computePICLabel(const std::string &FnName, const TargetAsmInfo *TAI, const X86Subtarget* Subtarget) { std::string label; if (Subtarget->isTargetDarwin()) - label = "\"L" + utostr_32(FnNum) + "$pb\""; + label = "\"L" "pb$" + FnName + "\""; else if (Subtarget->isTargetELF()) - label = ".Lllvm$" + utostr_32(FnNum) + "$piclabel"; + label = ".Lllvm$piclabel$" + FnName; else assert(0 && "Don't know how to print PIC label!\n"); @@ -236,13 +236,13 @@ case MachineOperand::MO_JumpTableIndex: { bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp) O << '$'; - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << "_" - << MO.getJumpTableIndex(); + O << TAI->getPrivateGlobalPrefix() << "JTI" << MO.getJumpTableIndex() + << '_' << CurrentFnName; if (TM.getRelocationModel() == Reloc::PIC_) { if (Subtarget->isPICStyleStub()) - O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << "$pb\""; + O << "-\"" << TAI->getPrivateGlobalPrefix() << "pb$" << CurrentFnName + << "\""; else if (Subtarget->isPICStyleGOT()) O << "@GOTOFF"; } @@ -254,13 +254,13 @@ case MachineOperand::MO_ConstantPoolIndex: { bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp) O << '$'; - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" - << MO.getConstantPoolIndex(); + O << TAI->getPrivateGlobalPrefix() << "CPI" << MO.getConstantPoolIndex() + << '_' << CurrentFnName; if (TM.getRelocationModel() == Reloc::PIC_) { if (Subtarget->isPICStyleStub()) - O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << "$pb\""; + O << "-\"" << TAI->getPrivateGlobalPrefix() << "pb$" << CurrentFnName + << "\""; else if (Subtarget->isPICStyleGOT()) O << "@GOTOFF"; } @@ -317,8 +317,8 @@ } if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_) - O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << "$pb\""; + O << "-\"" << TAI->getPrivateGlobalPrefix() << "pb$" << CurrentFnName + << "\""; } else { if (GV->hasDLLImportLinkage()) { O << "__imp_"; @@ -418,7 +418,7 @@ // popl %some_register // addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register O << " + [.-" - << computePICLabel(getFunctionNumber(), TAI, Subtarget) << "]"; + << computePICLabel(CurrentFnName, TAI, Subtarget) << "]"; if (isCallOp) O << "@PLT"; @@ -498,7 +498,7 @@ } void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { - std::string label = computePICLabel(getFunctionNumber(), TAI, Subtarget); + std::string label = computePICLabel(CurrentFnName, TAI, Subtarget); O << label << "\n" << label << ":"; } Index: lib/Target/X86/X86IntelAsmPrinter.cpp =================================================================== --- lib/Target/X86/X86IntelAsmPrinter.cpp (revision 42821) +++ lib/Target/X86/X86IntelAsmPrinter.cpp (working copy) @@ -140,15 +140,15 @@ case MachineOperand::MO_JumpTableIndex: { bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp) O << "OFFSET "; - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << "_" << MO.getJumpTableIndex(); + O << TAI->getPrivateGlobalPrefix() << "JTI" << MO.getJumpTableIndex() + << '_' << CurrentFnName; return; } case MachineOperand::MO_ConstantPoolIndex: { bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp) O << "OFFSET "; O << "[" << TAI->getPrivateGlobalPrefix() << "CPI" - << getFunctionNumber() << "_" << MO.getConstantPoolIndex(); + << MO.getConstantPoolIndex() << '_' << CurrentFnName; int Offset = MO.getOffset(); if (Offset > 0) O << " + " << Offset; @@ -236,8 +236,8 @@ } void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { - O << "\"L" << getFunctionNumber() << "$pb\"\n"; - O << "\"L" << getFunctionNumber() << "$pb\":"; + O << "\"L" "pb$" << CurrentFnName << "\"\n"; + O << "\"L" "pb$" << CurrentFnName << "\":"; } bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand &MO, From asl at math.spbu.ru Wed Oct 10 10:41:31 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Wed, 10 Oct 2007 19:41:31 +0400 Subject: [llvm-commits] RFC: internal label names In-Reply-To: <20071010143615.GR21991.SS22498SS@village.us.cray.com> References: <20071010143615.GR21991.SS22498SS@village.us.cray.com> Message-ID: <1192030891.21289.12.camel@asl.dorms.spbu.ru> Dan, > I saw this in another compiler and liked it. Does anyone here > dislike it? Patch looks pretty neat for me. -- With best regards, Anton Korobeynikov. Faculty of Mathematics & Mechanics, Saint Petersburg State University. From kremenek at apple.com Wed Oct 10 11:27:34 2007 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 10 Oct 2007 16:27:34 -0000 Subject: [llvm-commits] [llvm] r42825 - /llvm/trunk/include/llvm/ADT/ImmutableSet.h Message-ID: <200710101627.l9AGRYVh029571@zion.cs.uiuc.edu> Author: kremenek Date: Wed Oct 10 11:27:33 2007 New Revision: 42825 URL: http://llvm.org/viewvc/llvm-project?rev=42825&view=rev Log: Renamed internal method "Create" of ImutAVLTree to "CreateNode". Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=42825&r1=42824&r2=42825&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original) +++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Wed Oct 10 11:27:33 2007 @@ -26,6 +26,7 @@ template class ImutAVLFactory; + template class ImutAVLTree : public FoldingSetNode { struct ComputeIsEqual; @@ -34,6 +35,7 @@ typedef typename ImutInfo::value_type value_type; typedef typename ImutInfo::value_type_ref value_type_ref; typedef ImutAVLFactory Factory; + friend class ImutAVLFactory; //===----------------------------------------------------===// @@ -52,7 +54,7 @@ ImutAVLTree *T = this; while (T) { - key_type_ref CurrentKey = ImutInfo::KeyOfValue(Value(T)); + key_type_ref CurrentKey = ImutInfo::KeyOfValue(T->getValue()); if (ImutInfo::isEqual(K,CurrentKey)) return T; @@ -75,7 +77,6 @@ } - bool isEqual(const ImutAVLTree& RHS) const { // FIXME: Todo. return true; @@ -267,7 +268,7 @@ } //===--------------------------------------------------===// - // "Create" is used to generate new tree roots that link + // "CreateNode" is used to generate new tree roots that link // to other trees. The functon may also simply move links // in an existing root if that root is still marked mutable. // This is necessary because otherwise our balancing code @@ -276,7 +277,7 @@ // returned to the caller. //===--------------------------------------------------===// - TreeTy* Create(TreeTy* L, value_type_ref V, TreeTy* R) { + TreeTy* CreateNode(TreeTy* L, value_type_ref V, TreeTy* R) { FoldingSetNodeID ID; unsigned height = IncrementHeight(L,R); @@ -296,7 +297,7 @@ return T; } - TreeTy* Create(TreeTy* L, TreeTy* OldTree, TreeTy* R) { + TreeTy* CreateNode(TreeTy* L, TreeTy* OldTree, TreeTy* R) { assert (!isEmpty(OldTree)); if (OldTree->isMutable()) { @@ -305,7 +306,7 @@ OldTree->setHeight(IncrementHeight(L,R)); return OldTree; } - else return Create(L, Value(OldTree), R); + else return CreateNode(L, Value(OldTree), R); } /// Balance - Used by Add_internal and Remove_internal to @@ -323,7 +324,7 @@ TreeTy* LR = Right(L); if (Height(LL) >= Height(LR)) - return Create(LL, L, Create(LR,V,R)); + return CreateNode(LL, L, CreateNode(LR,V,R)); assert (!isEmpty(LR) && "LR cannot be empty because it has a height >= 1."); @@ -331,7 +332,7 @@ TreeTy* LRL = Left(LR); TreeTy* LRR = Right(LR); - return Create(Create(LL,L,LRL), LR, Create(LRR,V,R)); + return CreateNode(CreateNode(LL,L,LRL), LR, CreateNode(LRR,V,R)); } else if (hr > hl + 2) { assert (!isEmpty(R) && @@ -341,7 +342,7 @@ TreeTy* RR = Right(R); if (Height(RR) >= Height(RL)) - return Create(Create(L,V,RL), R, RR); + return CreateNode(CreateNode(L,V,RL), R, RR); assert (!isEmpty(RL) && "RL cannot be empty because it has a height >= 1."); @@ -349,10 +350,10 @@ TreeTy* RLL = Left(RL); TreeTy* RLR = Right(RL); - return Create(Create(L,V,RLL), RL, Create(RLR,R,RR)); + return CreateNode(CreateNode(L,V,RLL), RL, CreateNode(RLR,R,RR)); } else - return Create(L,V,R); + return CreateNode(L,V,R); } /// Add_internal - Creates a new tree that includes the specified @@ -360,7 +361,7 @@ /// already contained the data item, the original tree is returned. TreeTy* Add_internal(value_type_ref V, TreeTy* T) { if (isEmpty(T)) - return Create(T, V, T); + return CreateNode(T, V, T); assert (!T->isMutable()); @@ -368,7 +369,7 @@ key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T)); if (ImutInfo::isEqual(K,KCurrent)) - return Create(Left(T), V, Right(T)); + return CreateNode(Left(T), V, Right(T)); else if (ImutInfo::isLess(K,KCurrent)) return Balance(Add_internal(V,Left(T)), Value(T), Right(T)); else From evan.cheng at apple.com Wed Oct 10 11:33:30 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 10 Oct 2007 09:33:30 -0700 Subject: [llvm-commits] RFC: internal label names In-Reply-To: <20071010143615.GR21991@village.us.cray.com> References: <20071010143615.GR21991@village.us.cray.com> Message-ID: My only concern is it won't look as pleasant if the function name is long. Evan On Oct 10, 2007, at 7:36 AM, Dan Gohman wrote: > The attached patch changes the names of internal labels used by > codegen. In place of the "function number", which is a number that > codegen itself assigns specifically for this purpose, it uses the > (mangled) name of the function, which is already sufficiently unique. > > For example, what currently looks like this: > .LCPI1_3: > where 1 is the function number and 3 is the constant index would > look like this: > .LCPI3_foo: > Note that the constant index is now first, so the name can go last > to avoid problems with names containing underscores. > > I saw this in another compiler and liked it. Does anyone here > dislike it? > > Dan > > -- > Dan Gohman, Cray Inc. > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gabor at mac.com Wed Oct 10 11:57:18 2007 From: gabor at mac.com (Gabor Greif) Date: Wed, 10 Oct 2007 18:57:18 +0200 Subject: [llvm-commits] SPARC: Cannot yet select: 0x8733e8: i32, i32 = sdivrem 0x870470, 0x870528 Message-ID: <470D046E.2030300@mac.com> Recent changes broke this test: FAIL: /home/ggreif/llvm/test/CodeGen/Generic/BasicInstrs.llx Failed with signal(SIGABRT) at line 1 while running: llvm-upgrade < /home/ggreif/llvm/test/CodeGen/Generic/BasicInstrs.llx | llvm-as | llc .text .align 16 .globl add .type add, #function add: save -96, %o6, %o6 add %i0, %i1, %i0 restore %g0, %g0, %g0 retl nop .align 16 .globl sub .type sub, #function sub: save -96, %o6, %o6 sub %i0, %i1, %i0 restore %g0, %g0, %g0 retl nop .align 16 .globl mul .type mul, #function mul: save -96, %o6, %o6 smul %i0, %i1, %i0 restore %g0, %g0, %g0 retl nop .align 16 .globl sdiv .type sdiv, #function sdiv: save -96, %o6, %o6 sra %i0, 31, %l0 wr %l0, %g0, %y sdiv %i0, %i1, %i0 restore %g0, %g0, %g0 retl nop .align 16 .globl udiv .type udiv, #function udiv: save -96, %o6, %o6 wr %g0, %g0, %y udiv %i0, %i1, %i0 restore %g0, %g0, %g0 retl nop Cannot yet select: 0x8733e8: i32,i32 = sdivrem 0x870470, 0x870528 ------------------------- This is just a heads-up, I am not depending on it. Cheers, Gabor From clattner at apple.com Wed Oct 10 12:01:25 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 10 Oct 2007 10:01:25 -0700 Subject: [llvm-commits] RFC: internal label names In-Reply-To: References: <20071010143615.GR21991@village.us.cray.com> Message-ID: <2FDB30FE-58F5-4E99-A671-E8E8A6474DAA@apple.com> On Oct 10, 2007, at 9:33 AM, Evan Cheng wrote: > My only concern is it won't look as pleasant if the function name is > long. Which happens with C++ mangled names all the time :( a potentially solution to this (which may be over complex :) is to have two options: 1. if the name is short, print it as you propose. 2. if the name is long, print it with a number and optionally with a subset of the name (last 10 chars?) This could be implemented by just adding a new ivar like CurrentFunctionName that holds this. -Chris > > Evan > > On Oct 10, 2007, at 7:36 AM, Dan Gohman wrote: > >> The attached patch changes the names of internal labels used by >> codegen. In place of the "function number", which is a number that >> codegen itself assigns specifically for this purpose, it uses the >> (mangled) name of the function, which is already sufficiently unique. >> >> For example, what currently looks like this: >> .LCPI1_3: >> where 1 is the function number and 3 is the constant index would >> look like this: >> .LCPI3_foo: >> Note that the constant index is now first, so the name can go last >> to avoid problems with names containing underscores. >> >> I saw this in another compiler and liked it. Does anyone here >> dislike it? >> >> Dan >> >> -- >> Dan Gohman, Cray Inc. >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Wed Oct 10 12:35:13 2007 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 10 Oct 2007 17:35:13 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42827 - /llvm-gcc-4.0/tags/llvm-gcc-1200-18/ Message-ID: <200710101735.l9AHZDZP032093@zion.cs.uiuc.edu> Author: void Date: Wed Oct 10 12:35:13 2007 New Revision: 42827 URL: http://llvm.org/viewvc/llvm-project?rev=42827&view=rev Log: Creating llvm-gcc-1200-18 branch Added: llvm-gcc-4.0/tags/llvm-gcc-1200-18/ - copied from r42826, llvm-gcc-4.0/trunk/ From isanbard at gmail.com Wed Oct 10 12:35:19 2007 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 10 Oct 2007 17:35:19 -0000 Subject: [llvm-commits] [llvm] r42828 - /llvm/tags/Apple/llvm-1200-18/ Message-ID: <200710101735.l9AHZJxK032113@zion.cs.uiuc.edu> Author: void Date: Wed Oct 10 12:35:19 2007 New Revision: 42828 URL: http://llvm.org/viewvc/llvm-project?rev=42828&view=rev Log: Creating llvm-1200-18 branch Added: llvm/tags/Apple/llvm-1200-18/ - copied from r42827, llvm/trunk/ From sabre at nondot.org Wed Oct 10 13:10:58 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 10 Oct 2007 18:10:58 -0000 Subject: [llvm-commits] [llvm] r42832 - /llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp Message-ID: <200710101810.l9AIAwOZ001369@zion.cs.uiuc.edu> Author: lattner Date: Wed Oct 10 13:10:57 2007 New Revision: 42832 URL: http://llvm.org/viewvc/llvm-project?rev=42832&view=rev Log: Fix CodeGen/Generic/BasicInstrs.llx on sparc by marking divrem illegal. Thanks to gabor for pointing this out! Modified: llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp?rev=42832&r1=42831&r2=42832&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp Wed Oct 10 13:10:57 2007 @@ -149,9 +149,11 @@ setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); - // Sparc has no REM operation. + // Sparc has no REM or DIVREM operations. setOperationAction(ISD::UREM, MVT::i32, Expand); setOperationAction(ISD::SREM, MVT::i32, Expand); + setOperationAction(ISD::SDIVREM, MVT::i32, Expand); + setOperationAction(ISD::UDIVREM, MVT::i32, Expand); // Custom expand fp<->sint setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); From kremenek at apple.com Wed Oct 10 13:11:16 2007 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 10 Oct 2007 18:11:16 -0000 Subject: [llvm-commits] [llvm] r42833 - /llvm/trunk/include/llvm/ADT/ImmutableSet.h Message-ID: <200710101811.l9AIBGBx001398@zion.cs.uiuc.edu> Author: kremenek Date: Wed Oct 10 13:11:16 2007 New Revision: 42833 URL: http://llvm.org/viewvc/llvm-project?rev=42833&view=rev Log: Added preliminary support for iterators in ImutAVLTree. Implemented ImutAVLTree::isEqual. Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=42833&r1=42832&r2=42833&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original) +++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Wed Oct 10 13:11:16 2007 @@ -26,7 +26,8 @@ template class ImutAVLFactory; - +template class ImutAVLTreeInOrderIterator; + template class ImutAVLTree : public FoldingSetNode { struct ComputeIsEqual; @@ -34,10 +35,12 @@ typedef typename ImutInfo::key_type_ref key_type_ref; typedef typename ImutInfo::value_type value_type; typedef typename ImutInfo::value_type_ref value_type_ref; + typedef ImutAVLFactory Factory; - friend class ImutAVLFactory; + typedef ImutAVLTreeInOrderIterator iterator; + //===----------------------------------------------------===// // Public Interface. //===----------------------------------------------------===// @@ -76,10 +79,34 @@ return n; } + iterator begin() const { return iterator(this); } + iterator end() const { return iterator(); } bool isEqual(const ImutAVLTree& RHS) const { - // FIXME: Todo. - return true; + if (&RHS == this) + return true; + + iterator LItr = begin(), LEnd = end(); + iterator RItr = RHS.begin(), REnd = RHS.end(); + + while (LItr != LEnd && RItr != REnd) { + if (*LItr == *RItr) { + LItr.SkipSubTree(); + RItr.SkipSubTree(); + continue; + } + + // FIXME: need to compare data values, not key values, but our + // traits don't support this yet. + if (!ImutInfo::isEqual(ImutInfo::KeyOfValue(LItr->getValue()), + ImutInfo::KeyOfValue(RItr->getValue()))) + return false; + + ++LItr; + ++RItr; + } + + return LItr == LEnd && RItr == REnd; } bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual(RHS); } @@ -427,8 +454,195 @@ MarkImmutable(Right(T)); } }; + + +//===----------------------------------------------------------------------===// +// Immutable AVL-Tree Iterators. +//===----------------------------------------------------------------------===// + +template +class ImutAVLTreeGenericIterator { + SmallVector stack; +public: + enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3, + Flags=0x3 }; + + typedef ImutAVLTree TreeTy; + typedef ImutAVLTreeGenericIterator _Self; + inline ImutAVLTreeGenericIterator() {} + inline ImutAVLTreeGenericIterator(const TreeTy* Root) { + if (Root) stack.push_back(reinterpret_cast(Root)); + } + + TreeTy* operator*() const { + assert (!stack.empty()); + return reinterpret_cast(stack.back() & ~Flags); + } + + uintptr_t getVisitState() { + assert (!stack.empty()); + return stack.back() & Flags; + } + + + bool AtEnd() const { return stack.empty(); } + bool AtBeginning() const { + return stack.size() == 1 && getVisitState() == VisitedNone; + } + + void SkipToParent() { + assert (!stack.empty()); + stack.pop_back(); + + if (stack.empty()) + return; + + switch (getVisitState()) { + case VisitedNone: + stack.back() |= VisitedLeft; + break; + case VisitedLeft: + stack.back() |= VisitedRight; + break; + default: + assert (false && "Unreachable."); + } + } + + inline bool operator==(const _Self& x) const { + if (stack.size() != x.stack.size()) + return false; + + for (unsigned i = 0 ; i < stack.size(); i++) + if (stack[i] != x.stack[i]) + return false; + + return true; + } + + inline bool operator!=(const _Self& x) const { return !operator==(x); } + + _Self& operator++() { + assert (!stack.empty()); + + TreeTy* Current = reinterpret_cast(stack.back() & ~Flags); + assert (Current); + + switch (getVisitState()) { + case VisitedNone: + if (TreeTy* L = Current->getLeft()) + stack.push_back(reinterpret_cast(L)); + else + stack.back() |= VisitedLeft; + + break; + + case VisitedLeft: + if (TreeTy* R = Current->getRight()) + stack.push_back(reinterpret_cast(R)); + else + stack.back() |= VisitedRight; + + break; + + case VisitedRight: + SkipToParent(); + break; + + default: + assert (false && "Unreachable."); + } + + return *this; + } + + _Self& operator--() { + assert (!stack.empty()); + + TreeTy* Current = reinterpret_cast(stack.back() & ~Flags); + assert (Current); + + switch (getVisitState()) { + case VisitedNone: + stack.pop_back(); + break; + + case VisitedLeft: + stack.back() &= ~Flags; // Set state to "VisitedNone." + + if (TreeTy* L = Current->getLeft()) + stack.push_back(reinterpret_cast(L) | VisitedRight); + + break; + + case VisitedRight: + stack.back() &= ~Flags; + stack.back() |= VisitedLeft; + + if (TreeTy* R = Current->getRight()) + stack.push_back(reinterpret_cast(R) | VisitedRight); + + break; + + default: + assert (false && "Unreachable."); + } + + return *this; + } +}; + +template +class ImutAVLTreeInOrderIterator { + typedef ImutAVLTreeGenericIterator InternalIteratorTy; + InternalIteratorTy InternalItr; + +public: + typedef ImutAVLTree TreeTy; + typedef ImutAVLTreeInOrderIterator _Self; + + ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) { + if (Root) operator++(); // Advance to first element. + } + + ImutAVLTreeInOrderIterator() : InternalItr() {} + + inline bool operator==(const _Self& x) const { + return InternalItr == x.InternalItr; + } + + inline bool operator!=(const _Self& x) const { return !operator==(x); } + + inline TreeTy* operator*() { return *InternalItr; } + inline TreeTy* operator->() { return *InternalItr; } + + inline _Self& operator++() { + do ++InternalItr; + while (!InternalItr.AtEnd() && + InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft); + + return *this; + } + + inline _Self& operator--() { + do --InternalItr; + while (!InternalItr.AtBeginning() && + InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft); + + return *this; + } + + inline void SkipSubTree() { + InternalItr.SkipToParent(); + + while (!InternalItr.AtEnd() && + InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft) + ++InternalItr; + } +}; + //===----------------------------------------------------------------------===// // Trait classes for Profile information. //===----------------------------------------------------------------------===// From dalej at apple.com Wed Oct 10 13:14:01 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 10 Oct 2007 11:14:01 -0700 Subject: [llvm-commits] [llvm] r42822 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Target/PowerPC/PPCISelLowering.cpp lib/Target/PowerPC/PPCISelLowering.h lib/Target/PowerPC/PPCInstrFormats.td lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: References: <200710100101.l9A11Wo2016469@zion.cs.uiuc.edu> Message-ID: On Oct 10, 2007, at 12:19 AM, Evan Cheng wrote: > > On Oct 9, 2007, at 6:01 PM, Dale Johannesen wrote: > >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) >> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue Oct 9 >> 20:01:31 2007 >> @@ -403,6 +403,8 @@ >> SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT, >> const SDOperand *Ops, unsigned NumOps); >> SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, >> + MVT::ValueType VT2); >> + SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, >> MVT::ValueType VT2, SDOperand Op1); > > This seems unnecessary. You can use this variant: > SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, > MVT::ValueType VT2, > const SDOperand *Ops, unsigned NumOps); It's not me using it, it's tablegen. I could change that as you suggest but this seems simpler. No good reason not to support it, is there? > Ewww. :-) It just occurred to me you might want to implement this lot > with the usesCustomDAGSchedInserter = 1 hack. It allows you to expand > a pseudo PPC FP_ROUND_INREG node into multiple MI's at the end of > scheduling. It's also a hack but might be a little bit cleaner than > this. Sorry it didn't come to me when we were talking about this. :-( Yes, that would be cleaner. I'll push the rewrite on my stack, but I want to make progress in functionality. From evan.cheng at apple.com Wed Oct 10 13:44:45 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 10 Oct 2007 11:44:45 -0700 Subject: [llvm-commits] [llvm] r42822 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Target/PowerPC/PPCISelLowering.cpp lib/Target/PowerPC/PPCISelLowering.h lib/Target/PowerPC/PPCInstrFormats.td lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: References: <200710100101.l9A11Wo2016469@zion.cs.uiuc.edu> Message-ID: <7F76D7C6-E73C-4521-BD60-0329375BD4D2@apple.com> On Oct 10, 2007, at 11:14 AM, Dale Johannesen wrote: > > On Oct 10, 2007, at 12:19 AM, Evan Cheng wrote: > >> >> On Oct 9, 2007, at 6:01 PM, Dale Johannesen wrote: >> >>> >>> ==================================================================== >>> = >>> = >>> ======== >>> --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) >>> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue Oct 9 >>> 20:01:31 2007 >>> @@ -403,6 +403,8 @@ >>> SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT, >>> const SDOperand *Ops, unsigned NumOps); >>> SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, >>> + MVT::ValueType VT2); >>> + SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, >>> MVT::ValueType VT2, SDOperand Op1); >> >> This seems unnecessary. You can use this variant: >> SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, >> MVT::ValueType VT2, >> const SDOperand *Ops, unsigned NumOps); > > It's not me using it, it's tablegen. I could change that as you > suggest but > this seems simpler. No good reason not to support it, is there? Ah ok. I'll fix it then. Please file a bug so I remember it. :-) > >> Ewww. :-) It just occurred to me you might want to implement this lot >> with the usesCustomDAGSchedInserter = 1 hack. It allows you to expand >> a pseudo PPC FP_ROUND_INREG node into multiple MI's at the end of >> scheduling. It's also a hack but might be a little bit cleaner than >> this. Sorry it didn't come to me when we were talking about this. :-( > > Yes, that would be cleaner. I'll push the rewrite on my stack, but > I want > to make progress in functionality. Sounds good. Evan > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Wed Oct 10 13:45:17 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 10 Oct 2007 13:45:17 -0500 Subject: [llvm-commits] CVS: llvm-www/img/PhotoTed.jpg Message-ID: <200710101845.l9AIjHEP003215@zion.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoTed.jpg added (r1.1) --- Log message: add teh ted --- Diffs of the changes: (+0 -0) PhotoTed.jpg | 0 1 files changed Index: llvm-www/img/PhotoTed.jpg From sabre at nondot.org Wed Oct 10 13:45:17 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 10 Oct 2007 13:45:17 -0500 Subject: [llvm-commits] CVS: llvm-www/developers.txt Message-ID: <200710101845.l9AIjHRD003214@zion.cs.uiuc.edu> Changes in directory llvm-www: developers.txt updated: 1.16 -> 1.17 --- Log message: add teh ted --- Diffs of the changes: (+1 -0) developers.txt | 1 + 1 files changed, 1 insertion(+) Index: llvm-www/developers.txt diff -u llvm-www/developers.txt:1.16 llvm-www/developers.txt:1.17 --- llvm-www/developers.txt:1.16 Fri Oct 5 18:02:18 2007 +++ llvm-www/developers.txt Wed Oct 10 13:44:24 2007 @@ -14,6 +14,7 @@ Dale Johannesen href=http://llvm.org/ img=PhotoDale.png width=132 height=107 alt=Dale Brad Jones href=http://www.nondot.org/~kungfoomaster/ img=PhotoBrad.jpg width=200 height=171 alt=KungFooMaster Anton Korobeynikov href=mailto:asl_at_math_dot_spbu_dot_ru img=PhotoAnton.jpg width=239 height=207 alt=Anton +Ted Kremenek href=http://metacomp.stanford.edu/~kremenek/ img=PhotoTed.jpg width=159 height=240 alt=Ted Jim Laskey href=mailto:jlaskey at mac.com img=PhotoJim.jpg width=128 height=128 alt=Wickund Chris Lattner href=http://nondot.org/sabre/LLVMNotes/ img=PhotoChris.jpg width=150 height=152 alt=Sabre Tanya Lattner href=http://nondot.org/tonic/ img=PhotoTanya.jpg width=200 height=217 alt=tonic From dalej at apple.com Wed Oct 10 13:55:37 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 10 Oct 2007 11:55:37 -0700 Subject: [llvm-commits] [llvm] r42822 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Target/PowerPC/PPCISelLowering.cpp lib/Target/PowerPC/PPCISelLowering.h lib/Target/PowerPC/PPCInstrFormats.td lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: <7F76D7C6-E73C-4521-BD60-0329375BD4D2@apple.com> References: <200710100101.l9A11Wo2016469@zion.cs.uiuc.edu> <7F76D7C6-E73C-4521-BD60-0329375BD4D2@apple.com> Message-ID: <518CD5DE-7E33-46A1-9A05-7043618D00DE@apple.com> On Oct 10, 2007, at 11:44 AM, Evan Cheng wrote: >>>> --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) >>>> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue Oct 9 >>>> 20:01:31 2007 >>>> @@ -403,6 +403,8 @@ >>>> SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT, >>>> const SDOperand *Ops, unsigned NumOps); >>>> SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, >>>> + MVT::ValueType VT2); >>>> + SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, >>>> MVT::ValueType VT2, SDOperand Op1); >>> >>> This seems unnecessary. You can use this variant: >>> SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, >>> MVT::ValueType VT2, >>> const SDOperand *Ops, unsigned NumOps); >> >> It's not me using it, it's tablegen. I could change that as you >> suggest but >> this seems simpler. No good reason not to support it, is there? > > Ah ok. I'll fix it then. Please file a bug so I remember it. :-) OK, I guess, but I don't see what's wrong with this way. From evan.cheng at apple.com Wed Oct 10 14:26:47 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 10 Oct 2007 12:26:47 -0700 Subject: [llvm-commits] [llvm] r42822 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Target/PowerPC/PPCISelLowering.cpp lib/Target/PowerPC/PPCISelLowering.h lib/Target/PowerPC/PPCInstrFormats.td lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: <518CD5DE-7E33-46A1-9A05-7043618D00DE@apple.com> References: <200710100101.l9A11Wo2016469@zion.cs.uiuc.edu> <7F76D7C6-E73C-4521-BD60-0329375BD4D2@apple.com> <518CD5DE-7E33-46A1-9A05-7043618D00DE@apple.com> Message-ID: On Oct 10, 2007, at 11:55 AM, Dale Johannesen wrote: > On Oct 10, 2007, at 11:44 AM, Evan Cheng wrote: >>>>> --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) >>>>> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue Oct 9 >>>>> 20:01:31 2007 >>>>> @@ -403,6 +403,8 @@ >>>>> SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT, >>>>> const SDOperand *Ops, unsigned NumOps); >>>>> SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, >>>>> + MVT::ValueType VT2); >>>>> + SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, >>>>> MVT::ValueType VT2, SDOperand Op1); >>>> >>>> This seems unnecessary. You can use this variant: >>>> SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, >>>> MVT::ValueType VT2, >>>> const SDOperand *Ops, unsigned NumOps); >>> >>> It's not me using it, it's tablegen. I could change that as you >>> suggest but >>> this seems simpler. No good reason not to support it, is there? >> >> Ah ok. I'll fix it then. Please file a bug so I remember it. :-) > > OK, I guess, but I don't see what's wrong with this way. It's not "wrong". Just want to avoid unnecessary bloat. Evan > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From djg at cray.com Wed Oct 10 14:41:18 2007 From: djg at cray.com (Dan Gohman) Date: Wed, 10 Oct 2007 14:41:18 -0500 Subject: [llvm-commits] RFC: internal label names Message-ID: <20071010194118.GT21991@village.us.cray.com> >> My only concern is it won't look as pleasant if the function name is >> long. > > Which happens with C++ mangled names all the time :( > > a potentially solution to this (which may be over complex :) is to > have two options: > > 1. if the name is short, print it as you propose. > 2. if the name is long, print it with a number and optionally with a > subset of the name (last 10 chars?) > > This could be implemented by just adding a new ivar like > CurrentFunctionName that holds this. I think that is over complex :). C++ mangled names are ok with me here, but if they're unpleasant for others that's fine. Dan -- Dan Gohman, Cray Inc. From hartmut.kaiser at gmail.com Wed Oct 10 14:50:09 2007 From: hartmut.kaiser at gmail.com (Hartmut Kaiser) Date: Wed, 10 Oct 2007 19:50:09 -0000 Subject: [llvm-commits] [llvm] r42835 - in /llvm/trunk/win32: Analysis/Analysis.vcproj Bitcode/Bitcode.vcproj CodeGen/CodeGen.vcproj Support/Support.vcproj Transforms/Transforms.vcproj VMCore/VMCore.vcproj llvm.sln Message-ID: <200710101950.l9AJoAIH006453@zion.cs.uiuc.edu> Author: hkaiser Date: Wed Oct 10 14:50:09 2007 New Revision: 42835 URL: http://llvm.org/viewvc/llvm-project?rev=42835&view=rev Log: Updated VC++ build system. Modified: llvm/trunk/win32/Analysis/Analysis.vcproj llvm/trunk/win32/Bitcode/Bitcode.vcproj llvm/trunk/win32/CodeGen/CodeGen.vcproj llvm/trunk/win32/Support/Support.vcproj llvm/trunk/win32/Transforms/Transforms.vcproj llvm/trunk/win32/VMCore/VMCore.vcproj llvm/trunk/win32/llvm.sln Modified: llvm/trunk/win32/Analysis/Analysis.vcproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/Analysis/Analysis.vcproj?rev=42835&r1=42834&r2=42835&view=diff ============================================================================== --- llvm/trunk/win32/Analysis/Analysis.vcproj (original) +++ llvm/trunk/win32/Analysis/Analysis.vcproj Wed Oct 10 14:50:09 2007 @@ -182,6 +182,10 @@ > + + @@ -308,6 +312,10 @@ > + + Modified: llvm/trunk/win32/Bitcode/Bitcode.vcproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/Bitcode/Bitcode.vcproj?rev=42835&r1=42834&r2=42835&view=diff ============================================================================== --- llvm/trunk/win32/Bitcode/Bitcode.vcproj (original) +++ llvm/trunk/win32/Bitcode/Bitcode.vcproj Wed Oct 10 14:50:09 2007 @@ -185,6 +185,10 @@ > + + Modified: llvm/trunk/win32/CodeGen/CodeGen.vcproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/CodeGen/CodeGen.vcproj?rev=42835&r1=42834&r2=42835&view=diff ============================================================================== --- llvm/trunk/win32/CodeGen/CodeGen.vcproj (original) +++ llvm/trunk/win32/CodeGen/CodeGen.vcproj Wed Oct 10 14:50:09 2007 @@ -170,6 +170,14 @@ > + + + + @@ -270,6 +278,10 @@ > + + @@ -317,10 +329,6 @@ > - - @@ -352,6 +360,18 @@ > + + + + + + @@ -452,6 +472,10 @@ > + + Modified: llvm/trunk/win32/Support/Support.vcproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/Support/Support.vcproj?rev=42835&r1=42834&r2=42835&view=diff ============================================================================== --- llvm/trunk/win32/Support/Support.vcproj (original) +++ llvm/trunk/win32/Support/Support.vcproj Wed Oct 10 14:50:09 2007 @@ -41,7 +41,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="..\..\include;.." - PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_LIB;__STDC_LIMIT_MACROS" + PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN32;_DEBUG;_LIB;__STDC_LIMIT_MACROS" StringPooling="true" MinimalRebuild="true" BasicRuntimeChecks="3" @@ -111,7 +111,7 @@ + + @@ -388,6 +392,10 @@ > + + @@ -448,6 +456,10 @@ > + + @@ -480,6 +492,14 @@ > + + + + Modified: llvm/trunk/win32/Transforms/Transforms.vcproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/Transforms/Transforms.vcproj?rev=42835&r1=42834&r2=42835&view=diff ============================================================================== --- llvm/trunk/win32/Transforms/Transforms.vcproj (original) +++ llvm/trunk/win32/Transforms/Transforms.vcproj Wed Oct 10 14:50:09 2007 @@ -369,10 +369,6 @@ > - - Modified: llvm/trunk/win32/VMCore/VMCore.vcproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/VMCore/VMCore.vcproj?rev=42835&r1=42834&r2=42835&view=diff ============================================================================== --- llvm/trunk/win32/VMCore/VMCore.vcproj (original) +++ llvm/trunk/win32/VMCore/VMCore.vcproj Wed Oct 10 14:50:09 2007 @@ -183,6 +183,10 @@ > + + Modified: llvm/trunk/win32/llvm.sln URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/llvm.sln?rev=42835&r1=42834&r2=42835&view=diff ============================================================================== --- llvm/trunk/win32/llvm.sln (original) +++ llvm/trunk/win32/llvm.sln Wed Oct 10 14:50:09 2007 @@ -1,254 +1,377 @@ Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "support", "Support\Support.vcproj", "{28AA9146-3482-4F41-9CC6-407B1D258508}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TableGen", "TableGen\TableGen.vcproj", "{339C2249-26B6-4172-B484-85653029AF57}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Fibonacci", "Fibonacci\Fibonacci.vcproj", "{48FB551D-E37E-42EC-BC97-FF7219774867}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {144EEBF6-8C9B-4473-B715-2C821666AF6C} = {144EEBF6-8C9B-4473-B715-2C821666AF6C} - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {76295AE8-A083-460E-9F80-6F2B8923264A} = {76295AE8-A083-460E-9F80-6F2B8923264A} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} - {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} - {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} {0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08} + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} + {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {76295AE8-A083-460E-9F80-6F2B8923264A} = {76295AE8-A083-460E-9F80-6F2B8923264A} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} + {144EEBF6-8C9B-4473-B715-2C821666AF6C} = {144EEBF6-8C9B-4473-B715-2C821666AF6C} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExecutionEngine", "ExecutionEngine\ExecutionEngine.vcproj", "{76295AE8-A083-460E-9F80-6F2B8923264A}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VMCore", "VMCore\VMCore.vcproj", "{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57} {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Target", "Target\Target.vcproj", "{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CodeGen", "CodeGen\CodeGen.vcproj", "{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57} {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "System", "System\System.vcproj", "{0F8407F3-FA23-4CF1-83A9-DCBE0B361489}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Analysis", "Analysis\Analysis.vcproj", "{0622E827-8464-489D-8B1C-B0B496F35C08}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "x86", "x86\x86.vcproj", "{144EEBF6-8C9B-4473-B715-2C821666AF6C}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99} - {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} - {339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57} {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57} + {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} + {C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Transforms", "Transforms\Transforms.vcproj", "{C59374C1-9FC0-4147-B836-327DFDC52D99}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57} {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Configure", "Configure\Configure.vcproj", "{19514E48-456C-4B9D-8637-F2285476461E}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lli", "lli\lli.vcproj", "{FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {144EEBF6-8C9B-4473-B715-2C821666AF6C} = {144EEBF6-8C9B-4473-B715-2C821666AF6C} - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {76295AE8-A083-460E-9F80-6F2B8923264A} = {76295AE8-A083-460E-9F80-6F2B8923264A} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} - {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} - {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} {0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08} + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} + {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} + {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {76295AE8-A083-460E-9F80-6F2B8923264A} = {76295AE8-A083-460E-9F80-6F2B8923264A} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} + {144EEBF6-8C9B-4473-B715-2C821666AF6C} = {144EEBF6-8C9B-4473-B715-2C821666AF6C} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llc", "llc\llc.vcproj", "{ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {144EEBF6-8C9B-4473-B715-2C821666AF6C} = {144EEBF6-8C9B-4473-B715-2C821666AF6C} - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {057777CD-DED5-46DF-BF9A-6B76DE212549} = {057777CD-DED5-46DF-BF9A-6B76DE212549} - {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} - {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} - {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} {0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08} + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} + {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} + {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} + {057777CD-DED5-46DF-BF9A-6B76DE212549} = {057777CD-DED5-46DF-BF9A-6B76DE212549} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} + {144EEBF6-8C9B-4473-B715-2C821666AF6C} = {144EEBF6-8C9B-4473-B715-2C821666AF6C} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-dis", "llvm-dis\llvm-dis.vcproj", "{B13476BC-30AB-4EA0-BC1E-212C0A459405}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} - {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-as", "llvm-as\llvm-as.vcproj", "{4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {3DC216F5-1DDD-478A-84F8-C124E5C31982} = {3DC216F5-1DDD-478A-84F8-C124E5C31982} - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} - {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} + {3DC216F5-1DDD-478A-84F8-C124E5C31982} = {3DC216F5-1DDD-478A-84F8-C124E5C31982} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AsmParser", "AsmParser\AsmParser.vcproj", "{3DC216F5-1DDD-478A-84F8-C124E5C31982}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-ar", "llvm-ar\llvm-ar.vcproj", "{0FF2B75C-49C1-4B49-A44A-531C93000296}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} - {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-ranlib", "llvm-ranlib\llvm-ranlib.vcproj", "{BB16C7EE-B4ED-4714-B5ED-B775C62A6612}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} - {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-link", "llvm-link\llvm-link.vcproj", "{5E249789-49E1-4600-B12B-8AD2BB6439B2}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} - {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} + {342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Linker", "Linker\Linker.vcproj", "{342CF48F-760A-4040-A9A1-7D75AA2471CE}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CBackend", "CBackend\CBackend.vcproj", "{057777CD-DED5-46DF-BF9A-6B76DE212549}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opt", "opt\opt.vcproj", "{006D8B41-C3C7-4448-85E1-AF8907E591E5}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99} - {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} - {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} - {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} {0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08} + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} + {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} + {C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-bcanalyzer", "llvm-bcanalyzer\llvm-bcanalyzer.vcproj", "{E0B1E329-BE3E-456D-B372-5F397BE42C84}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-ld", "llvm-ld\llvm-ld.vcproj", "{64D8AA46-88DB-41F4-B837-053AE02406B8}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99} - {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} - {342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} - {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} - {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} {0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08} + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} + {342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE} + {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} + {C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-nm", "llvm-nm\llvm-nm.vcproj", "{5FF862CE-80A0-4B48-A80B-68AE325A0432}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} - {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-prof", "llvm-prof\llvm-prof.vcproj", "{ACBE81D9-64B1-4133-823A-807A4E60B454}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} - {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} - {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} {0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08} + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bugpoint", "bugpoint\bugpoint.vcproj", "{57249192-8E29-4D85-8B7A-FEFF1760B1DA}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {3DC216F5-1DDD-478A-84F8-C124E5C31982} = {3DC216F5-1DDD-478A-84F8-C124E5C31982} - {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} - {C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99} - {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} - {342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE} - {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} - {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} - {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} {0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08} + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} + {342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE} + {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} + {C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} + {3DC216F5-1DDD-478A-84F8-C124E5C31982} = {3DC216F5-1DDD-478A-84F8-C124E5C31982} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bitcode", "Bitcode\Bitcode.vcproj", "{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Archive", "Archive\Archive.vcproj", "{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection ProjectSection(ProjectDependencies) = postProject - {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} EndProjectSection EndProject Global + GlobalSection(DPCodeReviewSolutionGUID) = preSolution + DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000} + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Configure|Win32 = Configure|Win32 Debug|Win32 = Debug|Win32 From kremenek at apple.com Wed Oct 10 15:44:21 2007 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 10 Oct 2007 20:44:21 -0000 Subject: [llvm-commits] [llvm] r42837 - /llvm/trunk/include/llvm/ADT/ImmutableSet.h Message-ID: <200710102044.l9AKiLhN009423@zion.cs.uiuc.edu> Author: kremenek Date: Wed Oct 10 15:44:21 2007 New Revision: 42837 URL: http://llvm.org/viewvc/llvm-project?rev=42837&view=rev Log: Added some doxygen comments to a few methods of ImutAVLTree. Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=42837&r1=42836&r2=42837&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original) +++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Wed Oct 10 15:44:21 2007 @@ -45,14 +45,28 @@ // Public Interface. //===----------------------------------------------------===// - ImutAVLTree* getLeft() const { return reinterpret_cast(Left); } + /// getLeft - Returns a pointer to the left subtree. This value + /// is NULL if there is no left subtree. + ImutAVLTree* getLeft() const { + assert (!isMutable() && "Node is incorrectly marked mutable."); + + return reinterpret_cast(Left); + } + /// getRight - Returns a pointer to the right subtree. This value is + /// NULL if there is no right subtree. ImutAVLTree* getRight() const { return Right; } + + /// getHeight - Returns the height of the tree. A tree with no subtrees + /// has a height of 1. unsigned getHeight() const { return Height; } + /// getValue - Returns the data value associated with the tree node. const value_type& getValue() const { return Value; } + /// find - Finds the subtree associated with the specified key value. + /// This method returns NULL if no matching subtree is found. ImutAVLTree* find(key_type_ref K) { ImutAVLTree *T = this; @@ -70,6 +84,8 @@ return NULL; } + /// size - Returns the number of nodes in the tree, which includes + /// both leaves and non-leaf nodes. unsigned size() const { unsigned n = 1; @@ -79,9 +95,18 @@ return n; } + /// begin - Returns an iterator that iterates over the nodes of the tree + /// in an inorder traversal. The returned iterator thus refers to the + /// the tree node with the minimum data element. iterator begin() const { return iterator(this); } + + /// end - Returns an iterator for the tree that denotes the end of an + /// inorder traversal. iterator end() const { return iterator(); } + /// isEqual - Compares two trees for structural equality and returns true + /// if they are equal. This worst case performance of this operation is + // linear in the sizes of the trees. bool isEqual(const ImutAVLTree& RHS) const { if (&RHS == this) return true; @@ -108,11 +133,19 @@ return LItr == LEnd && RItr == REnd; } - + + /// isNotEqual - Compares two trees for structural inequality. Performance + /// is the same is isEqual. bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual(RHS); } + /// contains - Returns true if this tree contains a subtree (node) that + /// has an data element that matches the specified key. Complexity + /// is logarithmic in the size of the tree. bool contains(const key_type_ref K) { return (bool) find(K); } + /// foreach - A member template the accepts invokes operator() on a functor + /// object (specifed by Callback) for every node/subtree in the tree. + /// Nodes are visited using an inorder traversal. template void foreach(Callback& C) { if (ImutAVLTree* L = getLeft()) L->foreach(C); @@ -122,6 +155,12 @@ if (ImutAVLTree* R = getRight()) R->foreach(C); } + /// verify - A utility method that checks that the balancing and + /// ordering invariants of the tree are satisifed. It is a recursive + /// method that returns the height of the tree, which is then consumed + /// by the enclosing verify call. External callers should ignore the + /// return value. An invalid tree will cause an assertion to fire in + /// a debug build. unsigned verify() const { unsigned HL = getLeft() ? getLeft()->verify() : 0; unsigned HR = getRight() ? getRight()->verify() : 0; From kremenek at apple.com Wed Oct 10 15:45:34 2007 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 10 Oct 2007 20:45:34 -0000 Subject: [llvm-commits] [llvm] r42839 - /llvm/trunk/include/llvm/ADT/ImmutableSet.h Message-ID: <200710102045.l9AKjY1M009492@zion.cs.uiuc.edu> Author: kremenek Date: Wed Oct 10 15:45:34 2007 New Revision: 42839 URL: http://llvm.org/viewvc/llvm-project?rev=42839&view=rev Log: Removed spurious forward declaration to a structure that will no longer be used. Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=42839&r1=42838&r2=42839&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original) +++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Wed Oct 10 15:45:34 2007 @@ -30,7 +30,6 @@ template class ImutAVLTree : public FoldingSetNode { - struct ComputeIsEqual; public: typedef typename ImutInfo::key_type_ref key_type_ref; typedef typename ImutInfo::value_type value_type; From kremenek at apple.com Wed Oct 10 18:32:01 2007 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 10 Oct 2007 23:32:01 -0000 Subject: [llvm-commits] [llvm] r42847 - /llvm/trunk/include/llvm/ADT/ImmutableSet.h Message-ID: <200710102332.l9ANW1hB017705@zion.cs.uiuc.edu> Author: kremenek Date: Wed Oct 10 18:32:01 2007 New Revision: 42847 URL: http://llvm.org/viewvc/llvm-project?rev=42847&view=rev Log: Removed "height" of an AVL tree node from its Profile. This is implicitly captured by using the addresses of its children in the profile. Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=42847&r1=42846&r2=42847&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original) +++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Wed Oct 10 18:32:01 2007 @@ -201,17 +201,16 @@ static inline void Profile(FoldingSetNodeID& ID, ImutAVLTree* L, ImutAVLTree* R, - unsigned H, value_type_ref V) { + value_type_ref V) { ID.AddPointer(L); ID.AddPointer(R); - ID.AddInteger(H); ImutInfo::Profile(ID,V); } public: void Profile(FoldingSetNodeID& ID) { - Profile(ID,getSafeLeft(),getRight(),getHeight(),getValue()); + Profile(ID,getSafeLeft(),getRight(),getValue()); } //===----------------------------------------------------===// @@ -344,9 +343,7 @@ TreeTy* CreateNode(TreeTy* L, value_type_ref V, TreeTy* R) { FoldingSetNodeID ID; - unsigned height = IncrementHeight(L,R); - - TreeTy::Profile(ID,L,R,height,V); + TreeTy::Profile(ID,L,R,V); void* InsertPos; if (TreeTy* T = Cache.FindNodeOrInsertPos(ID,InsertPos)) @@ -356,7 +353,7 @@ // FIXME: more intelligent calculation of alignment. TreeTy* T = (TreeTy*) Allocator.Allocate(sizeof(*T),16); - new (T) TreeTy(L,R,V,height); + new (T) TreeTy(L,R,V,IncrementHeight(L,R)); Cache.InsertNode(T,InsertPos); return T; From kremenek at apple.com Wed Oct 10 18:35:07 2007 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 10 Oct 2007 23:35:07 -0000 Subject: [llvm-commits] [llvm] r42848 - /llvm/trunk/include/llvm/ADT/ImmutableSet.h Message-ID: <200710102335.l9ANZ7jT017835@zion.cs.uiuc.edu> Author: kremenek Date: Wed Oct 10 18:35:04 2007 New Revision: 42848 URL: http://llvm.org/viewvc/llvm-project?rev=42848&view=rev Log: Removed uninformative assertions that catch problems that will fire anyway at runtime due to a NULL dereference. Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=42848&r1=42847&r2=42848&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original) +++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Wed Oct 10 18:35:04 2007 @@ -302,28 +302,11 @@ //===--------------------------------------------------===// private: - bool isEmpty(TreeTy* T) const { - return !T; - } - - unsigned Height(TreeTy* T) const { - return T ? T->getHeight() : 0; - } - - TreeTy* Left(TreeTy* T) const { - assert (T); - return T->getSafeLeft(); - } - - TreeTy* Right(TreeTy* T) const { - assert (T); - return T->getRight(); - } - - value_type_ref Value(TreeTy* T) const { - assert (T); - return T->Value; - } + bool isEmpty(TreeTy* T) const { return !T; } + unsigned Height(TreeTy* T) const { return T ? T->getHeight() : 0; } + TreeTy* Left(TreeTy* T) const { return T->getSafeLeft(); } + TreeTy* Right(TreeTy* T) const { return T->getRight(); } + value_type_ref Value(TreeTy* T) const { return T->Value; } unsigned IncrementHeight(TreeTy* L, TreeTy* R) const { unsigned hl = Height(L); From clattner at apple.com Wed Oct 10 18:46:18 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 10 Oct 2007 16:46:18 -0700 Subject: [llvm-commits] RFC: internal label names In-Reply-To: <20071010194118.GT21991@village.us.cray.com> References: <20071010194118.GT21991@village.us.cray.com> Message-ID: <041FE40B-A167-4A4B-A5C2-A25930B8E7BC@apple.com> On Oct 10, 2007, at 12:41 PM, Dan Gohman wrote: >> 1. if the name is short, print it as you propose. >> 2. if the name is long, print it with a number and optionally with a >> subset of the name (last 10 chars?) >> >> This could be implemented by just adding a new ivar like >> CurrentFunctionName that holds this. > > I think that is over complex :). C++ mangled names are ok with me > here, > but if they're unpleasant for others that's fine. Ok, if you can convince Evan, I'm fine with it "ready: fight!" ;-) -Chris From kremenek at apple.com Wed Oct 10 18:47:04 2007 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 10 Oct 2007 23:47:04 -0000 Subject: [llvm-commits] [llvm] r42850 - /llvm/trunk/include/llvm/ADT/ImmutableSet.h Message-ID: <200710102347.l9ANl4qn018132@zion.cs.uiuc.edu> Author: kremenek Date: Wed Oct 10 18:47:03 2007 New Revision: 42850 URL: http://llvm.org/viewvc/llvm-project?rev=42850&view=rev Log: Added some doxygen comments to ImmutableSet. Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=42850&r1=42849&r2=42850&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original) +++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Wed Oct 10 18:47:03 2007 @@ -791,12 +791,27 @@ public: Factory() {} + /// GetEmptySet - Returns an immutable set that contains no elements. ImmutableSet GetEmptySet() { return ImmutableSet(F.GetEmptyTree()); } + /// Add - Creates a new immutable set that contains all of the values + /// of the original set with the addition of the specified value. If + /// the original set already included the value, then the original set is + /// returned and no memory is allocated. The time and space complexity + /// of this operation is logarithmic in the size of the original set. + /// The memory allocated to represent the set is released when the + /// factory object that created the set is destroyed. ImmutableSet Add(ImmutableSet Old, value_type_ref V) { return ImmutableSet(F.Add(Old.Root,V)); } + /// Remove - Creates a new immutable set that contains all of the values + /// of the original set with the exception of the specified value. If + /// the original set did not contain the value, the original set is + /// returned and no memory is allocated. The time and space complexity + /// of this operation is logarithmic in the size of the original set. + /// The memory allocated to represent the set is released when the + /// factory object that created the set is destroyed. ImmutableSet Remove(ImmutableSet Old, value_type_ref V) { return ImmutableSet(F.Remove(Old.Root,V)); } @@ -807,7 +822,8 @@ }; friend class Factory; - + + /// contains - Returns true if the set contains the specified value. bool contains(const value_type_ref V) const { return Root ? Root->contains(V) : false; } @@ -820,6 +836,7 @@ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root; } + /// isEmpty - Return true if the set contains no elements. bool isEmpty() const { return !Root; } template From kremenek at apple.com Wed Oct 10 19:14:49 2007 From: kremenek at apple.com (Ted Kremenek) Date: Thu, 11 Oct 2007 00:14:49 -0000 Subject: [llvm-commits] [llvm] r42851 - /llvm/trunk/include/llvm/ADT/ImmutableSet.h Message-ID: <200710110014.l9B0EnxX018780@zion.cs.uiuc.edu> Author: kremenek Date: Wed Oct 10 19:14:49 2007 New Revision: 42851 URL: http://llvm.org/viewvc/llvm-project?rev=42851&view=rev Log: Added iterators to ImmutableSet. Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=42851&r1=42850&r2=42851&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original) +++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Wed Oct 10 19:14:49 2007 @@ -633,8 +633,8 @@ inline bool operator!=(const _Self& x) const { return !operator==(x); } - inline TreeTy* operator*() { return *InternalItr; } - inline TreeTy* operator->() { return *InternalItr; } + inline TreeTy* operator*() const { return *InternalItr; } + inline TreeTy* operator->() const { return *InternalItr; } inline _Self& operator++() { do ++InternalItr; @@ -821,7 +821,7 @@ void operator=(const Factory& RHS) {}; }; - friend class Factory; + friend class Factory; /// contains - Returns true if the set contains the specified value. bool contains(const value_type_ref V) const { @@ -844,6 +844,27 @@ template void foreach() { if (Root) { Callback C; Root->foreach(C); } } + + //===--------------------------------------------------===// + // Iterators. + //===--------------------------------------------------===// + + class iterator { + typename TreeTy::iterator itr; + + iterator() {} + iterator(TreeTy* t) : itr(t) {} + friend class ImmutableSet; + public: + inline value_type_ref operator*() const { return itr->getValue(); } + inline iterator& operator++() { ++itr; return *this; } + inline iterator& operator--() { --itr; return *this; } + inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; } + inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; } + }; + + iterator begin() const { return iterator(Root); } + iterator end() const { return iterator(); } //===--------------------------------------------------===// // For testing. From sabre at nondot.org Wed Oct 10 23:18:11 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 11 Oct 2007 04:18:11 -0000 Subject: [llvm-commits] [llvm] r42859 - in /llvm/trunk/include/llvm: Support/CFG.h Use.h Message-ID: <200710110418.l9B4IBro025601@zion.cs.uiuc.edu> Author: lattner Date: Wed Oct 10 23:18:11 2007 New Revision: 42859 URL: http://llvm.org/viewvc/llvm-project?rev=42859&view=rev Log: Add a new use_iterator::atEnd() method, which allows us to shrink pred_iterator down to a single ivar. Modified: llvm/trunk/include/llvm/Support/CFG.h llvm/trunk/include/llvm/Use.h Modified: llvm/trunk/include/llvm/Support/CFG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CFG.h?rev=42859&r1=42858&r2=42859&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CFG.h (original) +++ llvm/trunk/include/llvm/Support/CFG.h Wed Oct 10 23:18:11 2007 @@ -29,7 +29,6 @@ template // Predecessor Iterator class PredIterator : public forward_iterator<_Ptr, ptrdiff_t> { typedef forward_iterator<_Ptr, ptrdiff_t> super; - _Ptr *BB; _USE_iterator It; public: typedef PredIterator<_Ptr,_USE_iterator> _Self; @@ -37,26 +36,26 @@ inline void advancePastNonTerminators() { // Loop to ignore non terminator uses (for example PHI nodes)... - while (It != BB->use_end() && !isa(*It)) + while (!It.atEnd() && !isa(*It)) ++It; } - inline PredIterator(_Ptr *bb) : BB(bb), It(bb->use_begin()) { + inline PredIterator(_Ptr *bb) : It(bb->use_begin()) { advancePastNonTerminators(); } - inline PredIterator(_Ptr *bb, bool) : BB(bb), It(bb->use_end()) {} + inline PredIterator(_Ptr *bb, bool) : It(bb->use_end()) {} inline bool operator==(const _Self& x) const { return It == x.It; } inline bool operator!=(const _Self& x) const { return !operator==(x); } inline pointer operator*() const { - assert(It != BB->use_end() && "pred_iterator out of range!"); + assert(!It.atEnd() && "pred_iterator out of range!"); return cast(*It)->getParent(); } inline pointer *operator->() const { return &(operator*()); } inline _Self& operator++() { // Preincrement - assert(It != BB->use_end() && "pred_iterator out of range!"); + assert(!It.atEnd() && "pred_iterator out of range!"); ++It; advancePastNonTerminators(); return *this; } Modified: llvm/trunk/include/llvm/Use.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Use.h?rev=42859&r1=42858&r2=42859&view=diff ============================================================================== --- llvm/trunk/include/llvm/Use.h (original) +++ llvm/trunk/include/llvm/Use.h Wed Oct 10 23:18:11 2007 @@ -120,6 +120,9 @@ bool operator!=(const _Self &x) const { return !operator==(x); } + + /// atEnd - return true if this iterator is equal to use_end() on the value. + bool atEnd() const { return U == 0; } // Iterator traversal: forward iteration only _Self &operator++() { // Preincrement From sabre at nondot.org Thu Oct 11 01:12:34 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 11 Oct 2007 06:12:34 -0000 Subject: [llvm-commits] [llvm] r42860 - /llvm/trunk/include/llvm/ADT/BitVector.h Message-ID: <200710110612.l9B6CYQD028431@zion.cs.uiuc.edu> Author: lattner Date: Thu Oct 11 01:12:33 2007 New Revision: 42860 URL: http://llvm.org/viewvc/llvm-project?rev=42860&view=rev Log: make bitvector &= do the right thing if vectors have mismatched length. Modified: llvm/trunk/include/llvm/ADT/BitVector.h Modified: llvm/trunk/include/llvm/ADT/BitVector.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/BitVector.h?rev=42860&r1=42859&r2=42860&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/BitVector.h (original) +++ llvm/trunk/include/llvm/ADT/BitVector.h Thu Oct 11 01:12:33 2007 @@ -274,9 +274,18 @@ // Intersection, union, disjoint union. BitVector operator&=(const BitVector &RHS) { - assert(Size == RHS.Size && "Illegal operation!"); - for (unsigned i = 0; i < NumBitWords(size()); ++i) + unsigned ThisWords = NumBitWords(size()); + unsigned RHSWords = NumBitWords(RHS.size()); + unsigned i; + for (i = 0; i != std::min(ThisWords, RHSWords); ++i) Bits[i] &= RHS.Bits[i]; + + // Any bits that are just in this bitvector become zero, because they aren't + // in the RHS bit vector. Any words only in RHS are ignored because they + // are already zero in the LHS. + for (; i != ThisWords; ++i) + Bits[i] = 0; + return *this; } From gabor at mac.com Thu Oct 11 05:52:10 2007 From: gabor at mac.com (Gabor Greif) Date: Thu, 11 Oct 2007 12:52:10 +0200 Subject: [llvm-commits] ExecutionEngine/2003-01-15-AlignmentTest.ll asserts on SPARC Message-ID: <470E005A.2070500@mac.com> Hi all, I get an ugly interpreter failure: Test Run By ggreif on Thu Oct 11 12:41:31 2007 Native configuration is sparc-sun-solaris2.9 === ExecutionEngine tests === Schedule of variations: unix Running target unix Using /home/ggreif/share/dejagnu/baseboards/unix.exp as board description file for target. Using /home/ggreif/share/dejagnu/config/unix.exp as generic interface file for target. WARNING: Couldn't find tool config file for unix, using default. Running /home/ggreif/llvm/test/ExecutionEngine/dg.exp ... FAIL: /home/ggreif/llvm/test/ExecutionEngine/2003-01-15-AlignmentTest.ll Failed with signal(SIGABRT) at line 2 while running: lli 2003-01-15-AlignmentTest.ll.tmp.bc > /dev/null Assertion failed: Result.PointerVal != 0 && "Null pointer returned by malloc!", file Execution.cpp, line 761 === ExecutionEngine Summary === # of expected passes 38 # of unexpected failures 1 make[1]: *** [check-local] Error 1 make[1]: Leaving directory `/home/ggreif/llvm/test' make: *** [check] Error 2 The problem comes from allocating a zero sized array, and actually I think malloc is allowed to return NULL on a call to malloc(0): ggreif at my [!187] cat /home/ggreif/llvm/test/ExecutionEngine/2003-01-15-AlignmentTest.ll ; RUN: llvm-upgrade %s | llvm-as -f -o %t.bc ; RUN: lli %t.bc > /dev/null int %bar(sbyte* %X) { %P = alloca double ; pointer should be 4 byte aligned! %R = cast double* %P to int %A = and int %R, 3 ret int %A } int %main() { %SP = alloca sbyte %X = add uint 0, 0 alloca sbyte, uint %X ; <<<<<<< Results in malloc(0) !!!! call int %bar(sbyte* %SP) ret int %0 } Using this patch: ggreif at my [!190] svn diff lib/ExecutionEngine/Interpreter/Execution.cpp Index: lib/ExecutionEngine/Interpreter/Execution.cpp =================================================================== --- lib/ExecutionEngine/Interpreter/Execution.cpp (revision 42860) +++ lib/ExecutionEngine/Interpreter/Execution.cpp (working copy) @@ -24,6 +24,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include +#include using namespace llvm; STATISTIC(NumDynamicInsts, "Number of dynamic instructions executed"); @@ -747,7 +748,7 @@ unsigned TypeSize = (size_t)TD.getTypeSize(Ty); - unsigned MemToAlloc = NumElements * TypeSize; + unsigned MemToAlloc = std::max(1U, NumElements * TypeSize); // Allocate enough memory to hold the type... void *Memory = malloc(MemToAlloc); the problem goes away. I am not sure whether this is an acceptable patch or we should find a more performant one :-) Cheers, Gabor From clattner at apple.com Thu Oct 11 10:14:59 2007 From: clattner at apple.com (Chris Lattner) Date: Thu, 11 Oct 2007 08:14:59 -0700 Subject: [llvm-commits] ExecutionEngine/2003-01-15-AlignmentTest.ll asserts on SPARC In-Reply-To: <470E005A.2070500@mac.com> References: <470E005A.2070500@mac.com> Message-ID: <7FC5C206-9AC4-4313-A117-03A9B7DFFB04@apple.com> On Oct 11, 2007, at 3:52 AM, Gabor Greif wrote: > Hi all, > > I get an ugly interpreter failure: The patch looks great to me, please apply! It would also be nice to add a "// avoid calls of malloc(0)." comment before it, -Chris > > > > Test Run By ggreif on Thu Oct 11 12:41:31 2007 > Native configuration is sparc-sun-solaris2.9 > > === ExecutionEngine tests === > > Schedule of variations: > unix > > Running target unix > Using /home/ggreif/share/dejagnu/baseboards/unix.exp as board > description file for target. > Using /home/ggreif/share/dejagnu/config/unix.exp as generic > interface file for target. > WARNING: Couldn't find tool config file for unix, using default. > Running /home/ggreif/llvm/test/ExecutionEngine/dg.exp ... > FAIL: /home/ggreif/llvm/test/ExecutionEngine/2003-01-15- > AlignmentTest.ll > Failed with signal(SIGABRT) at line 2 > while running: lli 2003-01-15-AlignmentTest.ll.tmp.bc > /dev/null > Assertion failed: Result.PointerVal != 0 && "Null pointer returned > by malloc!", file Execution.cpp, line 761 > > > === ExecutionEngine Summary === > > # of expected passes 38 > # of unexpected failures 1 > make[1]: *** [check-local] Error 1 > make[1]: Leaving directory `/home/ggreif/llvm/test' > make: *** [check] Error 2 > > > > The problem comes from allocating a zero sized array, > and actually I think malloc is allowed to return NULL > on a call to malloc(0): > > > > ggreif at my [!187] cat /home/ggreif/llvm/test/ExecutionEngine/ > 2003-01-15-AlignmentTest.ll > ; RUN: llvm-upgrade %s | llvm-as -f -o %t.bc > ; RUN: lli %t.bc > /dev/null > > > int %bar(sbyte* %X) { > %P = alloca double ; pointer should be 4 byte aligned! > %R = cast double* %P to int > %A = and int %R, 3 > ret int %A > } > > int %main() { > %SP = alloca sbyte > %X = add uint 0, 0 > alloca sbyte, uint %X ; <<<<<<< Results in malloc(0) !!!! > > call int %bar(sbyte* %SP) > ret int %0 > } > > > Using this patch: > > ggreif at my [!190] svn diff lib/ExecutionEngine/Interpreter/ > Execution.cpp > Index: lib/ExecutionEngine/Interpreter/Execution.cpp > =================================================================== > --- lib/ExecutionEngine/Interpreter/Execution.cpp (revision > 42860) > +++ lib/ExecutionEngine/Interpreter/Execution.cpp (working copy) > @@ -24,6 +24,7 @@ > #include "llvm/Support/Debug.h" > #include "llvm/Support/MathExtras.h" > #include > +#include > using namespace llvm; > > STATISTIC(NumDynamicInsts, "Number of dynamic instructions > executed"); > @@ -747,7 +748,7 @@ > > unsigned TypeSize = (size_t)TD.getTypeSize(Ty); > > - unsigned MemToAlloc = NumElements * TypeSize; > + unsigned MemToAlloc = std::max(1U, NumElements * TypeSize); > > // Allocate enough memory to hold the type... > void *Memory = malloc(MemToAlloc); > > > > the problem goes away. > > I am not sure whether this is an acceptable patch > or we should find a more performant one :-) > > Cheers, > > Gabor > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dpatel at apple.com Thu Oct 11 12:22:00 2007 From: dpatel at apple.com (Devang Patel) Date: Thu, 11 Oct 2007 17:22:00 -0000 Subject: [llvm-commits] [llvm] r42864 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll Message-ID: <200710111722.l9BHM0Ll024990@zion.cs.uiuc.edu> Author: dpatel Date: Thu Oct 11 12:21:57 2007 New Revision: 42864 URL: http://llvm.org/viewvc/llvm-project?rev=42864&view=rev Log: Lower memcpy if it makes sense. Added: llvm/trunk/test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=42864&r1=42863&r2=42864&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Thu Oct 11 12:21:57 2007 @@ -7669,6 +7669,52 @@ MI->setAlignment(ConstantInt::get(Type::Int32Ty, Align)); Changed = true; } + + // If MemCpyInst length is 1/2/4/8 bytes then replace memcpy with load/store + ConstantInt *MemOpLength = dyn_cast(CI.getOperand(3)); + if (isa(MI)) + if (MemOpLength) { + unsigned Size = MemOpLength->getZExtValue(); + unsigned Align = cast(CI.getOperand(4))->getZExtValue(); + const PointerType *PTy = cast(CI.getOperand(1)->getType()); + const Type *MTy = PTy->getElementType(); + PointerType *NewPtrTy = NULL; + if (MTy == Type::Int8Ty) { + if (Size == 8) + NewPtrTy = PointerType::get(Type::Int64Ty); + else if (Size == 4) + NewPtrTy = PointerType::get(Type::Int32Ty); + else if (Size == 2) + NewPtrTy = PointerType::get(Type::Int16Ty); + else if (Size == 1) + NewPtrTy = PointerType::get(Type::Int8Ty); + } else if (MTy == Type::Int16Ty) { + if (Size == 4) + NewPtrTy = PointerType::get(Type::Int64Ty); + else if (Size == 2) + NewPtrTy = PointerType::get(Type::Int32Ty); + else if (Size == 1) + NewPtrTy = PointerType::get(Type::Int16Ty); + } else if (MTy == Type::Int32Ty) { + if (Size == 2) + NewPtrTy = PointerType::get(Type::Int64Ty); + else if (Size == 1) + NewPtrTy = PointerType::get(Type::Int32Ty); + } else if (MTy == Type::Int64Ty) { + if (Size == 1) + NewPtrTy = PointerType::get(Type::Int64Ty); + } + if (NewPtrTy) + { + Value *Src = InsertCastBefore(Instruction::BitCast, CI.getOperand(2), NewPtrTy, CI); + Value *Dest = InsertCastBefore(Instruction::BitCast, CI.getOperand(1), NewPtrTy, CI); + Value *L = new LoadInst(Src, "tmp", false, Align, &CI); + Value *NS = new StoreInst(L, Dest, false, Align, &CI); + CI.replaceAllUsesWith(NS); + Changed = true; + return EraseInstFromFunction(CI); + } + } } else if (isa(MI)) { unsigned Alignment = GetOrEnforceKnownAlignment(MI->getDest(), TD); if (MI->getAlignment()->getZExtValue() < Alignment) { Added: llvm/trunk/test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll?rev=42864&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll Thu Oct 11 12:21:57 2007 @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep call + at .str = internal constant [4 x i8] c"xyz\00" ; <[4 x i8]*> [#uses=1] + +define void @foo(i8* %P) { +entry: + %P_addr = alloca i8* ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i8* %P, i8** %P_addr + %tmp = load i8** %P_addr, align 4 ; [#uses=1] + %tmp1 = getelementptr [4 x i8]* @.str, i32 0, i32 0 ; [#uses=1] + call void @llvm.memcpy.i32( i8* %tmp, i8* %tmp1, i32 4, i32 1 ) + br label %return + +return: ; preds = %entry + ret void +} + +declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) From dalej at apple.com Thu Oct 11 12:46:07 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 11 Oct 2007 10:46:07 -0700 Subject: [llvm-commits] [llvm] r42864 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll In-Reply-To: <200710111722.l9BHM0Ll024990@zion.cs.uiuc.edu> References: <200710111722.l9BHM0Ll024990@zion.cs.uiuc.edu> Message-ID: You aren't checking alignment when choosing the new pointer type. Are you sure this works on machines that don't have misaligned load/ store? In general memcpy handling is highly target specific. I'd be wary of doing too much in target-independent code, although I think the general idea here is OK. > + // If MemCpyInst length is 1/2/4/8 bytes then replace memcpy > with load/store > + ConstantInt *MemOpLength = dyn_cast > (CI.getOperand(3)); > + if (isa(MI)) > + if (MemOpLength) { > + unsigned Size = MemOpLength->getZExtValue(); > + unsigned Align = cast(CI.getOperand(4))- > >getZExtValue(); > + const PointerType *PTy = cast(CI.getOperand > (1)->getType()); > + const Type *MTy = PTy->getElementType(); > + PointerType *NewPtrTy = NULL; > + if (MTy == Type::Int8Ty) { > + if (Size == 8) > + NewPtrTy = PointerType::get(Type::Int64Ty); > + else if (Size == 4) > + NewPtrTy = PointerType::get(Type::Int32Ty); > + else if (Size == 2) > + NewPtrTy = PointerType::get(Type::Int16Ty); > + else if (Size == 1) > + NewPtrTy = PointerType::get(Type::Int8Ty); > + } else if (MTy == Type::Int16Ty) { > + if (Size == 4) > + NewPtrTy = PointerType::get(Type::Int64Ty); > + else if (Size == 2) > + NewPtrTy = PointerType::get(Type::Int32Ty); > + else if (Size == 1) > + NewPtrTy = PointerType::get(Type::Int16Ty); > + } else if (MTy == Type::Int32Ty) { > + if (Size == 2) > + NewPtrTy = PointerType::get(Type::Int64Ty); > + else if (Size == 1) > + NewPtrTy = PointerType::get(Type::Int32Ty); > + } else if (MTy == Type::Int64Ty) { > + if (Size == 1) > + NewPtrTy = PointerType::get(Type::Int64Ty); > + } > + if (NewPtrTy) > + { > + Value *Src = InsertCastBefore(Instruction::BitCast, > CI.getOperand(2), NewPtrTy, CI); > + Value *Dest = InsertCastBefore(Instruction::BitCast, > CI.getOperand(1), NewPtrTy, CI); > + Value *L = new LoadInst(Src, "tmp", false, Align, &CI); > + Value *NS = new StoreInst(L, Dest, false, Align, &CI); > + CI.replaceAllUsesWith(NS); > + Changed = true; > + return EraseInstFromFunction(CI); > + } > + } > } else if (isa(MI)) { > unsigned Alignment = GetOrEnforceKnownAlignment(MI->getDest > (), TD); > if (MI->getAlignment()->getZExtValue() < Alignment) { > > Added: llvm/trunk/test/Transforms/InstCombine/2007-10-10- > EliminateMemCpy.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ > InstCombine/2007-10-10-EliminateMemCpy.ll?rev=42864&view=auto > > ====================================================================== > ======== > --- llvm/trunk/test/Transforms/InstCombine/2007-10-10- > EliminateMemCpy.ll (added) > +++ llvm/trunk/test/Transforms/InstCombine/2007-10-10- > EliminateMemCpy.ll Thu Oct 11 12:21:57 2007 > @@ -0,0 +1,18 @@ > +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep call > + at .str = internal constant [4 x i8] c"xyz\00" ; <[4 x i8]*> [#uses=1] > + > +define void @foo(i8* %P) { > +entry: > + %P_addr = alloca i8* ; [#uses=2] > + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] > + store i8* %P, i8** %P_addr > + %tmp = load i8** %P_addr, align 4 ; [#uses=1] > + %tmp1 = getelementptr [4 x i8]* @.str, i32 0, i32 0 ; > [#uses=1] > + call void @llvm.memcpy.i32( i8* %tmp, i8* %tmp1, i32 4, i32 1 ) > + br label %return > + > +return: ; preds = %entry > + ret void > +} > + > +declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dpatel at apple.com Thu Oct 11 12:54:10 2007 From: dpatel at apple.com (Devang Patel) Date: Thu, 11 Oct 2007 10:54:10 -0700 Subject: [llvm-commits] [llvm] r42864 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll In-Reply-To: References: <200710111722.l9BHM0Ll024990@zion.cs.uiuc.edu> Message-ID: On Oct 11, 2007, at 10:46 AM, Dale Johannesen wrote: > You aren't checking alignment when choosing the new pointer type. > Are you sure this works on machines that don't have misaligned load/ > store? > > In general memcpy handling is highly target specific. I'd be wary > of doing too > much in target-independent code, although I think the general idea > here is OK. I'm expecting target specific code generator to handle this if it is handling unaligned memcpy. No ? - Devang From dalej at apple.com Thu Oct 11 13:01:47 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 11 Oct 2007 11:01:47 -0700 Subject: [llvm-commits] [llvm] r42864 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll In-Reply-To: References: <200710111722.l9BHM0Ll024990@zion.cs.uiuc.edu> Message-ID: On Oct 11, 2007, at 10:54 AM, Devang Patel wrote: > > On Oct 11, 2007, at 10:46 AM, Dale Johannesen wrote: > >> You aren't checking alignment when choosing the new pointer type. >> Are you sure this works on machines that don't have misaligned >> load/store? >> >> In general memcpy handling is highly target specific. I'd be wary >> of doing too >> much in target-independent code, although I think the general idea >> here is OK. > > I'm expecting target specific code generator to handle this if it > is handling unaligned memcpy. > No ? Might well work, I'm not sure what order things are done in. Could you try it? PPC for example. From dalej at apple.com Thu Oct 11 13:07:30 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 11 Oct 2007 18:07:30 -0000 Subject: [llvm-commits] [llvm] r42865 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/AsmParser/Lexer.cpp.cvs lib/AsmParser/Lexer.l lib/AsmParser/Lexer.l.cvs lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Writer/BitcodeWriter.cpp lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/Support/APFloat.cpp lib/VMCore/AsmWriter.cpp lib/VMCore/Constants.cpp Message-ID: <200710111807.l9BI7UxF026854@zion.cs.uiuc.edu> Author: johannes Date: Thu Oct 11 13:07:22 2007 New Revision: 42865 URL: http://llvm.org/viewvc/llvm-project?rev=42865&view=rev Log: Next PPC long double bits. First cut at constants. No compile-time support for constant operations yet, just format transformations. Make readers and writers work. Split constants into 2 doubles in Legalize. Modified: llvm/trunk/include/llvm/ADT/APFloat.h llvm/trunk/lib/AsmParser/Lexer.cpp.cvs llvm/trunk/lib/AsmParser/Lexer.l llvm/trunk/lib/AsmParser/Lexer.l.cvs llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/Support/APFloat.cpp llvm/trunk/lib/VMCore/AsmWriter.cpp llvm/trunk/lib/VMCore/Constants.cpp Modified: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=42865&r1=42864&r2=42865&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (original) +++ llvm/trunk/include/llvm/ADT/APFloat.h Thu Oct 11 13:07:22 2007 @@ -126,6 +126,7 @@ static const fltSemantics IEEEsingle; static const fltSemantics IEEEdouble; static const fltSemantics IEEEquad; + static const fltSemantics PPCDoubleDouble; static const fltSemantics x87DoubleExtended; /* And this psuedo, used to construct APFloats that cannot conflict with anything real. */ @@ -175,7 +176,7 @@ APFloat(const fltSemantics &, fltCategory, bool negative); explicit APFloat(double d); explicit APFloat(float f); - explicit APFloat(const APInt &); + explicit APFloat(const APInt &, bool isIEEE = false); APFloat(const APFloat &); ~APFloat(); @@ -276,10 +277,12 @@ APInt convertFloatAPFloatToAPInt() const; APInt convertDoubleAPFloatToAPInt() const; APInt convertF80LongDoubleAPFloatToAPInt() const; - void initFromAPInt(const APInt& api); + APInt convertPPCDoubleDoubleAPFloatToAPInt() const; + void initFromAPInt(const APInt& api, bool isIEEE = false); void initFromFloatAPInt(const APInt& api); void initFromDoubleAPInt(const APInt& api); void initFromF80LongDoubleAPInt(const APInt& api); + void initFromPPCDoubleDoubleAPInt(const APInt& api); void assign(const APFloat &); void copySignificand(const APFloat &); @@ -306,6 +309,13 @@ /* The sign bit of this number. */ unsigned int sign: 1; + + /* For PPCDoubleDouble, we have a second exponent and sign (the second + significand is appended to the first one, although it would be wrong to + regard these as a single number for arithmetic purposes). These fields + are not meaningful for any other type. */ + exponent_t exponent2 : 11; + unsigned int sign2: 1; }; } /* namespace llvm */ Modified: llvm/trunk/lib/AsmParser/Lexer.cpp.cvs URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/Lexer.cpp.cvs?rev=42865&r1=42864&r2=42865&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/Lexer.cpp.cvs (original) +++ llvm/trunk/lib/AsmParser/Lexer.cpp.cvs Thu Oct 11 13:07:22 2007 @@ -2199,7 +2199,7 @@ #line 488 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" { uint64_t Pair[2]; HexToIntPair(yytext+3, Pair); - llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair)); + llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair), true); return FPVAL; } YY_BREAK Modified: llvm/trunk/lib/AsmParser/Lexer.l URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/Lexer.l?rev=42865&r1=42864&r2=42865&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/Lexer.l (original) +++ llvm/trunk/lib/AsmParser/Lexer.l Thu Oct 11 13:07:22 2007 @@ -487,7 +487,7 @@ } {HexFP128Constant} { uint64_t Pair[2]; HexToIntPair(yytext+3, Pair); - llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair)); + llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair), true); return FPVAL; } {HexPPC128Constant} { uint64_t Pair[2]; Modified: llvm/trunk/lib/AsmParser/Lexer.l.cvs URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/Lexer.l.cvs?rev=42865&r1=42864&r2=42865&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/Lexer.l.cvs (original) +++ llvm/trunk/lib/AsmParser/Lexer.l.cvs Thu Oct 11 13:07:22 2007 @@ -487,7 +487,7 @@ } {HexFP128Constant} { uint64_t Pair[2]; HexToIntPair(yytext+3, Pair); - llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair)); + llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair), true); return FPVAL; } {HexPPC128Constant} { uint64_t Pair[2]; Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=42865&r1=42864&r2=42865&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Thu Oct 11 13:07:22 2007 @@ -632,9 +632,9 @@ else if (CurTy == Type::X86_FP80Ty) V = ConstantFP::get(CurTy, APFloat(APInt(80, 2, &Record[0]))); else if (CurTy == Type::FP128Ty) - V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0]))); + V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0]), true)); else if (CurTy == Type::PPC_FP128Ty) - assert(0 && "PowerPC long double constants not handled yet."); + V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0]))); else V = UndefValue::get(CurTy); break; Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=42865&r1=42864&r2=42865&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Thu Oct 11 13:07:22 2007 @@ -534,13 +534,11 @@ const uint64_t *p = api.getRawData(); Record.push_back(p[0]); Record.push_back((uint16_t)p[1]); - } else if (Ty == Type::FP128Ty) { + } else if (Ty == Type::FP128Ty || Ty == Type::PPC_FP128Ty) { APInt api = CFP->getValueAPF().convertToAPInt(); const uint64_t *p = api.getRawData(); Record.push_back(p[0]); Record.push_back(p[1]); - } else if (Ty == Type::PPC_FP128Ty) { - assert(0 && "PowerPC long double constants not handled yet."); } else { assert (0 && "Unknown FP type!"); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=42865&r1=42864&r2=42865&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Oct 11 13:07:22 2007 @@ -5196,6 +5196,14 @@ } case ISD::ConstantFP: { ConstantFPSDNode *CFP = cast(Node); + if (CFP->getValueType(0) == MVT::ppcf128) { + APInt api = CFP->getValueAPF().convertToAPInt(); + Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &api.getRawData()[1])), + MVT::f64); + Hi = DAG.getConstantFP(APFloat(APInt(64, 1, &api.getRawData()[0])), + MVT::f64); + break; + } Lo = ExpandConstantFP(CFP, false, DAG, TLI); if (getTypeAction(Lo.getValueType()) == Expand) ExpandOp(Lo, Lo, Hi); Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=42865&r1=42864&r2=42865&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Thu Oct 11 13:07:22 2007 @@ -50,6 +50,11 @@ const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, true }; const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64, false }; const fltSemantics APFloat::Bogus = { 0, 0, 0, false }; + + // The PowerPC format consists of two doubles. It does not map cleanly + // onto the usual format above. For now only storage of constants of + // this type is supported, no arithmetic. + const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022, 106, true }; } /* Put a bunch of private, handy routines in an anonymous namespace. */ @@ -325,6 +330,8 @@ sign = rhs.sign; category = rhs.category; exponent = rhs.exponent; + sign2 = rhs.sign2; + exponent2 = rhs.exponent2; if(category == fcNormal || category == fcNaN) copySignificand(rhs); } @@ -361,10 +368,16 @@ category != rhs.category || sign != rhs.sign) return false; + if (semantics==(const llvm::fltSemantics* const)&PPCDoubleDouble && + sign2 != rhs.sign2) + return false; if (category==fcZero || category==fcInfinity) return true; else if (category==fcNormal && exponent!=rhs.exponent) return false; + else if (semantics==(const llvm::fltSemantics* const)&PPCDoubleDouble && + exponent2!=rhs.exponent2) + return false; else { int i= partCount(); const integerPart* p=significandParts(); @@ -379,6 +392,8 @@ APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); initialize(&ourSemantics); sign = 0; zeroSignificand(); @@ -390,6 +405,8 @@ APFloat::APFloat(const fltSemantics &ourSemantics, fltCategory ourCategory, bool negative) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); initialize(&ourSemantics); category = ourCategory; sign = negative; @@ -399,6 +416,8 @@ APFloat::APFloat(const fltSemantics &ourSemantics, const char *text) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); initialize(&ourSemantics); convertFromString(text, rmNearestTiesToEven); } @@ -1181,6 +1200,8 @@ APFloat::opStatus APFloat::add(const APFloat &rhs, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); return addOrSubtract(rhs, rounding_mode, false); } @@ -1188,6 +1209,8 @@ APFloat::opStatus APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); return addOrSubtract(rhs, rounding_mode, true); } @@ -1195,6 +1218,8 @@ APFloat::opStatus APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); opStatus fs; sign ^= rhs.sign; @@ -1214,6 +1239,8 @@ APFloat::opStatus APFloat::divide(const APFloat &rhs, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); opStatus fs; sign ^= rhs.sign; @@ -1233,6 +1260,8 @@ APFloat::opStatus APFloat::mod(const APFloat &rhs, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); opStatus fs; APFloat V = *this; unsigned int origSign = sign; @@ -1269,6 +1298,8 @@ const APFloat &addend, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); opStatus fs; /* Post-multiplication sign, before addition. */ @@ -1312,6 +1343,8 @@ APFloat::cmpResult APFloat::compare(const APFloat &rhs) const { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); cmpResult result; assert(semantics == rhs.semantics); @@ -1385,6 +1418,8 @@ APFloat::convert(const fltSemantics &toSemantics, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); lostFraction lostFraction; unsigned int newPartCount, oldPartCount; opStatus fs; @@ -1462,6 +1497,8 @@ bool isSigned, roundingMode rounding_mode) const { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); lostFraction lost_fraction; unsigned int msb, partsCount; int bits; @@ -1591,6 +1628,8 @@ bool isSigned, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); opStatus status; if (isSigned @@ -1618,6 +1657,8 @@ unsigned int width, bool isSigned, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); unsigned int partCount = partCountForBits(width); APInt api = APInt(width, partCount, parts); @@ -1634,6 +1675,8 @@ APFloat::convertFromHexadecimalString(const char *p, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); lostFraction lost_fraction; integerPart *significand; unsigned int bitPos, partsCount; @@ -1713,6 +1756,8 @@ APFloat::opStatus APFloat::convertFromString(const char *p, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); /* Handle a leading minus sign. */ if(*p == '-') sign = 1, p++; @@ -1754,6 +1799,8 @@ APFloat::convertToHexString(char *dst, unsigned int hexDigits, bool upperCase, roundingMode rounding_mode) const { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); char *p; p = dst; @@ -1962,6 +2009,51 @@ } APInt +APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const +{ + assert(semantics == (const llvm::fltSemantics* const)&PPCDoubleDouble); + assert (partCount()==2); + + uint64_t myexponent, mysignificand, myexponent2, mysignificand2; + + if (category==fcNormal) { + myexponent = exponent + 1023; //bias + myexponent2 = exponent2 + 1023; + mysignificand = significandParts()[0]; + mysignificand2 = significandParts()[1]; + if (myexponent==1 && !(mysignificand & 0x10000000000000LL)) + myexponent = 0; // denormal + if (myexponent2==1 && !(mysignificand2 & 0x10000000000000LL)) + myexponent2 = 0; // denormal + } else if (category==fcZero) { + myexponent = 0; + mysignificand = 0; + myexponent2 = 0; + mysignificand2 = 0; + } else if (category==fcInfinity) { + myexponent = 0x7ff; + myexponent2 = 0; + mysignificand = 0; + mysignificand2 = 0; + } else { + assert(category == fcNaN && "Unknown category"); + myexponent = 0x7ff; + mysignificand = significandParts()[0]; + myexponent2 = exponent2; + mysignificand2 = significandParts()[1]; + } + + uint64_t words[2]; + words[0] = (((uint64_t)sign & 1) << 63) | + ((myexponent & 0x7ff) << 52) | + (mysignificand & 0xfffffffffffffLL); + words[1] = (((uint64_t)sign2 & 1) << 63) | + ((myexponent2 & 0x7ff) << 52) | + (mysignificand2 & 0xfffffffffffffLL); + return APInt(128, 2, words); +} + +APInt APFloat::convertDoubleAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&IEEEdouble); @@ -2020,6 +2112,10 @@ (mysignificand & 0x7fffff))); } +// This function creates an APInt that is just a bit map of the floating +// point constant as it would appear in memory. It is not a conversion, +// and treating the result as a normal integer is unlikely to be useful. + APInt APFloat::convertToAPInt() const { @@ -2029,6 +2125,9 @@ if (semantics == (const llvm::fltSemantics* const)&IEEEdouble) return convertDoubleAPFloatToAPInt(); + if (semantics == (const llvm::fltSemantics* const)&PPCDoubleDouble) + return convertPPCDoubleDoubleAPFloatToAPInt(); + assert(semantics == (const llvm::fltSemantics* const)&x87DoubleExtended && "unknown format!"); return convertF80LongDoubleAPFloatToAPInt(); @@ -2091,6 +2190,56 @@ } void +APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) +{ + assert(api.getBitWidth()==128); + uint64_t i1 = api.getRawData()[0]; + uint64_t i2 = api.getRawData()[1]; + uint64_t myexponent = (i1 >> 52) & 0x7ff; + uint64_t mysignificand = i1 & 0xfffffffffffffLL; + uint64_t myexponent2 = (i2 >> 52) & 0x7ff; + uint64_t mysignificand2 = i2 & 0xfffffffffffffLL; + + initialize(&APFloat::PPCDoubleDouble); + assert(partCount()==2); + + sign = i1>>63; + sign2 = i2>>63; + if (myexponent==0 && mysignificand==0) { + // exponent, significand meaningless + // exponent2 and significand2 are required to be 0; we don't check + category = fcZero; + } else if (myexponent==0x7ff && mysignificand==0) { + // exponent, significand meaningless + // exponent2 and significand2 are required to be 0; we don't check + category = fcInfinity; + } else if (myexponent==0x7ff && mysignificand!=0) { + // exponent meaningless. So is the whole second word, but keep it + // for determinism. + category = fcNaN; + exponent2 = myexponent2; + significandParts()[0] = mysignificand; + significandParts()[1] = mysignificand2; + } else { + category = fcNormal; + // Note there is no category2; the second word is treated as if it is + // fcNormal, although it might be something else considered by itself. + exponent = myexponent - 1023; + exponent2 = myexponent2 - 1023; + significandParts()[0] = mysignificand; + significandParts()[1] = mysignificand2; + if (myexponent==0) // denormal + exponent = -1022; + else + significandParts()[0] |= 0x10000000000000LL; // integer bit + if (myexponent2==0) + exponent2 = -1022; + else + significandParts()[1] |= 0x10000000000000LL; // integer bit + } +} + +void APFloat::initFromDoubleAPInt(const APInt &api) { assert(api.getBitWidth()==64); @@ -2157,11 +2306,11 @@ } /// Treat api as containing the bits of a floating point number. Currently -/// we infer the floating point type from the size of the APInt. FIXME: This -/// breaks when we get to PPC128 and IEEE128 (but both cannot exist in the -/// same compile...) +/// we infer the floating point type from the size of the APInt. The +/// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful +/// when the size is anything else). void -APFloat::initFromAPInt(const APInt& api) +APFloat::initFromAPInt(const APInt& api, bool isIEEE) { if (api.getBitWidth() == 32) return initFromFloatAPInt(api); @@ -2169,13 +2318,15 @@ return initFromDoubleAPInt(api); else if (api.getBitWidth()==80) return initFromF80LongDoubleAPInt(api); + else if (api.getBitWidth()==128 && !isIEEE) + return initFromPPCDoubleDoubleAPInt(api); else assert(0); } -APFloat::APFloat(const APInt& api) +APFloat::APFloat(const APInt& api, bool isIEEE) { - initFromAPInt(api); + initFromAPInt(api, isIEEE); } APFloat::APFloat(float f) Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=42865&r1=42864&r2=42865&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original) +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Thu Oct 11 13:07:22 2007 @@ -519,6 +519,8 @@ Out << 'K'; else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad) Out << 'L'; + else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble) + Out << 'M'; else assert(0 && "Unsupported floating point type"); // api needed to prevent premature destruction @@ -526,7 +528,7 @@ const uint64_t* p = api.getRawData(); uint64_t word = *p; int shiftcount=60; - int width = CFP->getValueAPF().convertToAPInt().getBitWidth(); + int width = api.getBitWidth(); for (int j=0; j>shiftcount) & 15; if (nibble < 10) @@ -535,7 +537,7 @@ Out << (unsigned char)(nibble - 10 + 'A'); if (shiftcount == 0) { word = *(++p); - shiftcount = 60; + shiftcount = 64; if (width-j-4 < 64) shiftcount = width-j-4; } Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=42865&r1=42864&r2=42865&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Thu Oct 11 13:07:22 2007 @@ -114,6 +114,7 @@ case Type::X86_FP80TyID: return ConstantFP::get(Ty, APFloat(APInt(80, 2, zero))); case Type::FP128TyID: + return ConstantFP::get(Ty, APFloat(APInt(128, 2, zero), true)); case Type::PPC_FP128TyID: return ConstantFP::get(Ty, APFloat(APInt(128, 2, zero))); case Type::PointerTyID: @@ -256,6 +257,8 @@ assert(&V.getSemantics()==&APFloat::x87DoubleExtended); else if (Ty==Type::FP128Ty) assert(&V.getSemantics()==&APFloat::IEEEquad); + else if (Ty==Type::PPC_FP128Ty) + assert(&V.getSemantics()==&APFloat::PPCDoubleDouble); else assert(0); } @@ -320,6 +323,8 @@ assert(&V.getSemantics()==&APFloat::x87DoubleExtended); else if (Ty==Type::FP128Ty) assert(&V.getSemantics()==&APFloat::IEEEquad); + else if (Ty==Type::PPC_FP128Ty) + assert(&V.getSemantics()==&APFloat::PPCDoubleDouble); else assert(0); @@ -747,6 +752,10 @@ return &Val2.getSemantics() == &APFloat::IEEEsingle || &Val2.getSemantics() == &APFloat::IEEEdouble || &Val2.getSemantics() == &APFloat::IEEEquad; + case Type::PPC_FP128TyID: + return &Val2.getSemantics() == &APFloat::IEEEsingle || + &Val2.getSemantics() == &APFloat::IEEEdouble || + &Val2.getSemantics() == &APFloat::PPCDoubleDouble; } } From tonic at nondot.org Thu Oct 11 13:37:13 2007 From: tonic at nondot.org (Tanya Lattner) Date: Thu, 11 Oct 2007 18:37:13 -0000 Subject: [llvm-commits] [nightly-test-server] r42867 - /nightly-test-server/trunk/AcceptTestResults.php Message-ID: <200710111837.l9BIbEm3028636@zion.cs.uiuc.edu> Author: tbrethou Date: Thu Oct 11 13:37:13 2007 New Revision: 42867 URL: http://llvm.org/viewvc/llvm-project?rev=42867&view=rev Log: Fix typos in accept results script. Modified: nightly-test-server/trunk/AcceptTestResults.php Modified: nightly-test-server/trunk/AcceptTestResults.php URL: http://llvm.org/viewvc/llvm-project/nightly-test-server/trunk/AcceptTestResults.php?rev=42867&r1=42866&r2=42867&view=diff ============================================================================== --- nightly-test-server/trunk/AcceptTestResults.php (original) +++ nightly-test-server/trunk/AcceptTestResults.php Thu Oct 11 13:37:13 2007 @@ -415,8 +415,8 @@ // Add new test run config -$testRunConfigId = addTestRunConfig($runDateTime, $machineId, $machineUname, - $gccVersion, $cvsCpuTime, $cvsWallTime, +$testRunConfigId = addTestRunConfig($runDateTime, $machineId, $uname, + $gcc_version, $cvsCpuTime, $cvsWallTime, $configureCpuTime, $configureWallTime, $buildCpuTime, $buildWallTime, $dejagnuCpuTime, From ggreif at gmail.com Thu Oct 11 14:40:38 2007 From: ggreif at gmail.com (Gabor Greif) Date: Thu, 11 Oct 2007 19:40:38 -0000 Subject: [llvm-commits] [llvm] r42871 - /llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp Message-ID: <200710111940.l9BJeciI031962@zion.cs.uiuc.edu> Author: ggreif Date: Thu Oct 11 14:40:35 2007 New Revision: 42871 URL: http://llvm.org/viewvc/llvm-project?rev=42871&view=rev Log: Fix an assertion abort on sparc. malloc(0) is allowed to return NULL. Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp?rev=42871&r1=42870&r2=42871&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp Thu Oct 11 14:40:35 2007 @@ -24,6 +24,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include +#include using namespace llvm; STATISTIC(NumDynamicInsts, "Number of dynamic instructions executed"); @@ -747,7 +748,8 @@ unsigned TypeSize = (size_t)TD.getTypeSize(Ty); - unsigned MemToAlloc = NumElements * TypeSize; + // Avoid malloc-ing zero bytes, use max()... + unsigned MemToAlloc = std::max(1U, NumElements * TypeSize); // Allocate enough memory to hold the type... void *Memory = malloc(MemToAlloc); From dalej at apple.com Thu Oct 11 14:41:40 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 11 Oct 2007 19:41:40 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42872 - in /llvm-gcc-4.0/trunk/gcc: llvm-convert.cpp llvm-types.cpp Message-ID: <200710111941.l9BJfeFC032023@zion.cs.uiuc.edu> Author: johannes Date: Thu Oct 11 14:41:40 2007 New Revision: 42872 URL: http://llvm.org/viewvc/llvm-project?rev=42872&view=rev Log: Emit PPC long doubles correctly (they aren't actually generated yet). Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp?rev=42872&r1=42871&r2=42872&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Thu Oct 11 14:41:40 2007 @@ -5690,6 +5690,16 @@ UArr[1] = (uint16_t)RealArr[0]; return ConstantFP::get(Ty, APFloat(APInt(80, 2, UArr))); + } else if (Ty==Type::PPC_FP128Ty) { + long RealArr[4]; + uint64_t UArr[2]; + REAL_VALUE_TO_TARGET_LONG_DOUBLE(TREE_REAL_CST(exp), RealArr); + + UArr[0] = ((uint64_t)((uint32_t)RealArr[0]) << 32) | + ((uint64_t)((uint32_t)RealArr[1])); + UArr[1] = ((uint64_t)((uint32_t)RealArr[2]) << 32) | + ((uint64_t)((uint32_t)RealArr[3])); + return ConstantFP::get(Ty, APFloat(APInt(128, 2, UArr))); } assert(0 && "Floating point type not handled yet"); return 0; // outwit compiler warning Modified: llvm-gcc-4.0/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-types.cpp?rev=42872&r1=42871&r2=42872&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Thu Oct 11 14:41:40 2007 @@ -705,10 +705,17 @@ case 64: return SET_TYPE_LLVM(type, Type::DoubleTy); case 80: return SET_TYPE_LLVM(type, Type::X86_FP80Ty); case 128: +#ifdef TARGET_POWERPC + return SET_TYPE_LLVM(type, Type::PPC_FP128Ty); +#elif 0 + // This is for IEEE double extended, e.g. Sparc + return SET_TYPE_LLVM(type, Type::FP128Ty); +#else // 128-bit long doubles map onto { double, double }. const Type *Ty = Type::DoubleTy; Ty = StructType::get(std::vector(2, Ty), false); return SET_TYPE_LLVM(type, Ty); +#endif } case COMPLEX_TYPE: { From dalej at apple.com Thu Oct 11 14:47:52 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 11 Oct 2007 19:47:52 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r42873 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-types.cpp Message-ID: <200710111947.l9BJlqng032252@zion.cs.uiuc.edu> Author: johannes Date: Thu Oct 11 14:47:49 2007 New Revision: 42873 URL: http://llvm.org/viewvc/llvm-project?rev=42873&view=rev Log: Emit PPC long double correctly (it's not actually generated yet) Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=42873&r1=42872&r2=42873&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Oct 11 14:47:49 2007 @@ -5253,6 +5253,16 @@ UArr[1] = (uint16_t)RealArr[0]; return ConstantFP::get(Ty, APFloat(APInt(80, 2, UArr))); + } else if (Ty==Type::PPC_FP128Ty) { + long RealArr[4]; + uint64_t UArr[2]; + REAL_VALUE_TO_TARGET_LONG_DOUBLE(TREE_REAL_CST(exp), RealArr); + + UArr[0] = ((uint64_t)((uint32_t)RealArr[0]) << 32) | + ((uint64_t)((uint32_t)RealArr[1])); + UArr[1] = ((uint64_t)((uint32_t)RealArr[2]) << 32) | + ((uint64_t)((uint32_t)RealArr[3])); + return ConstantFP::get(Ty, APFloat(APInt(128, 2, UArr))); } assert(0 && "Floating point type not handled yet"); return 0; // outwit compiler warning Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=42873&r1=42872&r2=42873&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Thu Oct 11 14:47:49 2007 @@ -722,10 +722,17 @@ case 64: return SET_TYPE_LLVM(type, Type::DoubleTy); case 80: return SET_TYPE_LLVM(type, Type::X86_FP80Ty); case 128: +#ifdef TARGET_POWERPC + return SET_TYPE_LLVM(type, Type::PPC_FP128Ty); +#elif 0 + // This is for IEEE double extended, e.g. Sparc + return SET_TYPE_LLVM(type, Type::FP128Ty); +#else // 128-bit long doubles map onto { double, double }. const Type *Ty = Type::DoubleTy; Ty = StructType::get(std::vector(2, Ty), false); return SET_TYPE_LLVM(type, Ty); +#endif } case COMPLEX_TYPE: { From dalej at apple.com Thu Oct 11 15:58:38 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 11 Oct 2007 20:58:38 -0000 Subject: [llvm-commits] [llvm] r42874 - /llvm/trunk/lib/Target/X86/X86InstrSSE.td Message-ID: <200710112058.l9BKwc24003046@zion.cs.uiuc.edu> Author: johannes Date: Thu Oct 11 15:58:37 2007 New Revision: 42874 URL: http://llvm.org/viewvc/llvm-project?rev=42874&view=rev Log: Add missing argument to PALIGNR Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=42874&r1=42873&r2=42874&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Thu Oct 11 15:58:37 2007 @@ -2598,14 +2598,14 @@ let isTwoAddress = 1 in { def PALIGNR64rr : SS3AI<0x0F, MRMSrcReg, (outs VR64:$dst), (ins VR64:$src1, VR64:$src2, i16imm:$src3), - "palignr\t{$src2, $dst|$dst, $src2}", + "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}", [(set VR64:$dst, (int_x86_ssse3_palign_r VR64:$src1, VR64:$src2, imm:$src3))]>; def PALIGNR64rm : SS3AI<0x0F, MRMSrcReg, (outs VR64:$dst), (ins VR64:$src1, i64mem:$src2, i16imm:$src3), - "palignr\t{$src2, $dst|$dst, $src2}", + "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}", [(set VR64:$dst, (int_x86_ssse3_palign_r VR64:$src1, @@ -2614,14 +2614,14 @@ def PALIGNR128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32imm:$src3), - "palignr\t{$src2, $dst|$dst, $src2}", + "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}", [(set VR128:$dst, (int_x86_ssse3_palign_r_128 VR128:$src1, VR128:$src2, imm:$src3))]>, OpSize; def PALIGNR128rm : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2, i32imm:$src3), - "palignr\t{$src2, $dst|$dst, $src2}", + "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}", [(set VR128:$dst, (int_x86_ssse3_palign_r_128 VR128:$src1, From isanbard at gmail.com Thu Oct 11 16:15:16 2007 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 11 Oct 2007 21:15:16 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42875 - /llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Message-ID: <200710112115.l9BLFHl7003778@zion.cs.uiuc.edu> Author: void Date: Thu Oct 11 16:15:15 2007 New Revision: 42875 URL: http://llvm.org/viewvc/llvm-project?rev=42875&view=rev Log: Explicit convert needed. Modified: llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Modified: llvm-gcc-4.0/trunk/gcc/objc/objc-act.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/objc/objc-act.c?rev=42875&r1=42874&r2=42875&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Thu Oct 11 16:15:15 2007 @@ -12240,8 +12240,11 @@ } else /* APPLE LOCAL LLVM - begin NUL pointer */ - super_expr = convert (string_type_node, - build_int_cst (NULL_TREE, 0)); + { + super_expr = convert (string_type_node, + build_int_cst (NULL_TREE, 0)); + super_expr = build_c_cast (cast_type, super_expr); /* cast! */ + } /* APPLE LOCAL LLVM - end NUL pointer */ root_expr = add_objc_string (my_root_id, class_names); From isanbard at gmail.com Thu Oct 11 16:15:50 2007 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 11 Oct 2007 21:15:50 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r42876 - /llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Message-ID: <200710112115.l9BLFo8D003802@zion.cs.uiuc.edu> Author: void Date: Thu Oct 11 16:15:49 2007 New Revision: 42876 URL: http://llvm.org/viewvc/llvm-project?rev=42876&view=rev Log: Explicit cast needed Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/objc-act.c?rev=42876&r1=42875&r2=42876&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Thu Oct 11 16:15:49 2007 @@ -12135,8 +12135,11 @@ } else /* APPLE LOCAL LLVM - begin NUL pointer */ - super_expr = convert (string_type_node, - build_int_cst (NULL_TREE, 0)); + { + super_expr = convert (string_type_node, + build_int_cst (NULL_TREE, 0)); + super_expr = build_c_cast (cast_type, super_expr); /* cast! */ + } /* APPLE LOCAL LLVM - end NUL pointer */ root_expr = add_objc_string (my_root_id, class_names); From arnold.schwaighofer at gmail.com Thu Oct 11 13:54:49 2007 From: arnold.schwaighofer at gmail.com (Arnold Schwaighofer) Date: Thu, 11 Oct 2007 18:54:49 -0000 Subject: [llvm-commits] [llvm] r42869 - /llvm/trunk/CREDITS.TXT Message-ID: <200710111854.l9BIsnrS029557@zion.cs.uiuc.edu> Author: arnolds Date: Thu Oct 11 13:54:49 2007 New Revision: 42869 URL: http://llvm.org/viewvc/llvm-project?rev=42869&view=rev Log: Adding myself Modified: llvm/trunk/CREDITS.TXT Modified: llvm/trunk/CREDITS.TXT URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/CREDITS.TXT?rev=42869&r1=42868&r2=42869&view=diff ============================================================================== --- llvm/trunk/CREDITS.TXT (original) +++ llvm/trunk/CREDITS.TXT Thu Oct 11 13:54:49 2007 @@ -229,6 +229,10 @@ E: sasanka at uiuc.edu D: Graph coloring register allocator for the Sparc64 backend +N: Arnold Schwaighofer +E: arnold.schwaighofer at gmail.com +D: Tail call optimization for the x86 backend + N: Anand Shukla E: ashukla at cs.uiuc.edu D: The `paths' pass From arnold.schwaighofer at gmail.com Thu Oct 11 14:40:11 2007 From: arnold.schwaighofer at gmail.com (Arnold Schwaighofer) Date: Thu, 11 Oct 2007 19:40:11 -0000 Subject: [llvm-commits] [llvm] r42870 - in /llvm/trunk: include/llvm/Target/ lib/CodeGen/SelectionDAG/ lib/Target/ lib/Target/X86/ test/CodeGen/X86/ Message-ID: <200710111940.l9BJeCqc031930@zion.cs.uiuc.edu> Author: arnolds Date: Thu Oct 11 14:40:01 2007 New Revision: 42870 URL: http://llvm.org/viewvc/llvm-project?rev=42870&view=rev Log: Added tail call optimization to the x86 back end. It can be enabled by passing -tailcallopt to llc. The optimization is performed if the following conditions are satisfied: * caller/callee are fastcc * elf/pic is disabled OR elf/pic enabled + callee is in module + callee has visibility protected or hidden Added: llvm/trunk/test/CodeGen/X86/tailcall1.ll llvm/trunk/test/CodeGen/X86/tailcallpic1.ll llvm/trunk/test/CodeGen/X86/tailcallpic2.ll Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/include/llvm/Target/TargetOptions.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/Target/TargetMachine.cpp llvm/trunk/lib/Target/X86/README.txt llvm/trunk/lib/Target/X86/X86CallingConv.td llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.td llvm/trunk/lib/Target/X86/X86InstrX86-64.td llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=42870&r1=42869&r2=42870&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Thu Oct 11 14:40:01 2007 @@ -860,6 +860,15 @@ /// implement this. The default implementation of this aborts. virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); + /// IsEligibleForTailCallOptimization - Check whether the call is eligible for + /// tail call optimization. Target which want to do tail call optimization + /// should implement this function. + virtual bool IsEligibleForTailCallOptimization(SDOperand Call, + SDOperand Ret, + SelectionDAG &DAG) const { + return false; + } + /// CustomPromoteOperation - This callback is invoked for operations that are /// unsupported by the target, are registered to use 'custom' lowering, and /// whose type needs to be promoted. Modified: llvm/trunk/include/llvm/Target/TargetOptions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetOptions.h?rev=42870&r1=42869&r2=42870&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetOptions.h (original) +++ llvm/trunk/include/llvm/Target/TargetOptions.h Thu Oct 11 14:40:01 2007 @@ -73,6 +73,11 @@ /// ExceptionHandling - This flag indicates that exception information should /// be emitted. extern bool ExceptionHandling; + + /// PerformTailCallOpt - This flag is enabled when the -tailcallopt is + /// specified on the commandline. When the flag is on, the target will perform + /// tail call optimization (pop the caller's stack) providing it supports it. + extern bool PerformTailCallOpt; } // End llvm namespace #endif Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=42870&r1=42869&r2=42870&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Oct 11 14:40:01 2007 @@ -4444,6 +4444,48 @@ } } +/// CheckDAGForTailCallsAndFixThem - This Function looks for CALL nodes in the +/// DAG and fixes their tailcall attribute operand +static void CheckDAGForTailCallsAndFixThem(SelectionDAG &DAG, + TargetLowering& TLI) { + SDNode * Ret = NULL; + SDOperand Terminator = DAG.getRoot(); + + // Find RET node. + if (Terminator.getOpcode() == ISD::RET) { + Ret = Terminator.Val; + } + + // Fix tail call attribute of CALL nodes. + for (SelectionDAG::allnodes_iterator BE = DAG.allnodes_begin(), + BI = prior(DAG.allnodes_end()); BI != BE; --BI) { + if (BI->getOpcode() == ISD::CALL) { + SDOperand OpRet(Ret, 0); + SDOperand OpCall(static_cast(BI), 0); + bool isMarkedTailCall = + cast(OpCall.getOperand(3))->getValue() != 0; + // If CALL node has tail call attribute set to true and the call is not + // eligible (no RET or the target rejects) the attribute is fixed to + // false. The TargetLowering::IsEligibleForTailCallOptimization function + // must correctly identify tail call optimizable calls. + if (isMarkedTailCall && + (Ret==NULL || + !TLI.IsEligibleForTailCallOptimization(OpCall, OpRet, DAG))) { + SmallVector Ops; + unsigned idx=0; + for(SDNode::op_iterator I =OpCall.Val->op_begin(), + E=OpCall.Val->op_end(); I!=E; I++, idx++) { + if (idx!=3) + Ops.push_back(*I); + else + Ops.push_back(DAG.getConstant(false, TLI.getPointerTy())); + } + DAG.UpdateNodeOperands(OpCall, Ops.begin(), Ops.size()); + } + } + } +} + void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB, std::vector > &PHINodesToUpdate, FunctionLoweringInfo &FuncInfo) { @@ -4621,6 +4663,12 @@ // Make sure the root of the DAG is up-to-date. DAG.setRoot(SDL.getRoot()); + + // Check whether calls in this block are real tail calls. Fix up CALL nodes + // with correct tailcall attribute so that the target can rely on the tailcall + // attribute indicating whether the call is really eligible for tail call + // optimization. + CheckDAGForTailCallsAndFixThem(DAG, TLI); } void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) { Modified: llvm/trunk/lib/Target/TargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetMachine.cpp?rev=42870&r1=42869&r2=42870&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetMachine.cpp (original) +++ llvm/trunk/lib/Target/TargetMachine.cpp Thu Oct 11 14:40:01 2007 @@ -33,6 +33,7 @@ bool ExceptionHandling; Reloc::Model RelocationModel; CodeModel::Model CMModel; + bool PerformTailCallOpt; } namespace { cl::opt PrintCode("print-machineinstrs", @@ -116,6 +117,12 @@ clEnumValN(CodeModel::Large, "large", " Large code model"), clEnumValEnd)); + + cl::opt + EnablePerformTailCallOpt("tailcallopt", + cl::desc("Turn on tail call optimization."), + cl::location(PerformTailCallOpt), + cl::init(false)); } //--------------------------------------------------------------------------- Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=42870&r1=42869&r2=42870&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Thu Oct 11 14:40:01 2007 @@ -1368,3 +1368,83 @@ L5: //===---------------------------------------------------------------------===// +Tail call optimization improvements: Tail call optimization currently +pushes all arguments on the top of the stack (their normal place if +that was a not tail call optimized functiong call ) before moving them +to actual stack slot. this is done to prevent overwriting of paramters +(see example below) that might be used, since the arguments of the +callee overwrites callers arguments. + + example: + +int callee(int32, int64); +int caller(int32 arg1, int32 arg2) { + int64 local = arg2 * 2; + return callee(arg2, (int64)local); +} + +[arg1] [!arg2 no longer valid since we moved local onto it] +[arg2] -> [(int64) +[RETADDR] local ] + +moving arg1 onto the stack slot of callee function would overwrite +arg2 of the caller. + +Possible optimizations: + + - only push those arguments to the top of the stack that are actual + parameters of the caller function and have no local value in the + caller + + in above example local does not need to be pushed onto the top of + the stack as it is definitetly not a caller's function parameter + + - analyse the actual parameters of the callee to see which would + overwrite a caller paramter which is used by the callee and only + push them onto the top of the stack + + int callee (int32 arg1, int32 arg2); + int caller (int32 arg1, int32 arg2) { + return callee(arg1,arg2); + } + + here we don't need to write any variables to the top of the stack + since they don't overwrite each other + + int callee (int32 arg1, int32 arg2); + int caller (int32 arg1, int32 arg2) { + return callee(arg2,arg1); + } + + here we need to push the arguments because they overwrite each other + + + code for lowering directly onto callers arguments: ++ SmallVector, 8> RegsToPass; ++ SmallVector MemOpChains; ++ ++ SDOperand FramePtr; ++ SDOperand PtrOff; ++ SDOperand FIN; ++ int FI = 0; ++ // Walk the register/memloc assignments, inserting copies/loads. ++ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { ++ CCValAssign &VA = ArgLocs[i]; ++ SDOperand Arg = Op.getOperand(5+2*VA.getValNo()); ++ ++ .... ++ ++ if (VA.isRegLoc()) { ++ RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); ++ } else { ++ assert(VA.isMemLoc()); ++ // create frame index ++ int32_t Offset = VA.getLocMemOffset()+FPDiff; ++ uint32_t OpSize = (MVT::getSizeInBits(VA.getLocVT())+7)/8; ++ FI = MF.getFrameInfo()->CreateFixedObject(OpSize, Offset); ++ FIN = DAG.getFrameIndex(FI, MVT::i32); ++ // store relative to framepointer ++ MemOpChains.push_back(DAG.getStore(Chain, Arg, FIN, NULL, 0)); ++ } ++ } +//===---------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallingConv.td?rev=42870&r1=42869&r2=42870&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CallingConv.td (original) +++ llvm/trunk/lib/Target/X86/X86CallingConv.td Thu Oct 11 14:40:01 2007 @@ -127,6 +127,40 @@ CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToStack<8, 8>> ]>; +// tail call convetion (fast) one register is reserved for target address +// namely R9 +def CC_X86_64_TailCall : CallingConv<[ + // Promote i8/i16 arguments to i32. + CCIfType<[i8, i16], CCPromoteToType>, + + CCIfStruct>, + + // The first 6 integer arguments are passed in integer registers. + CCIfType<[i32], CCAssignToReg<[EDI, ESI, EDX, ECX, R8D]>>, + CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8]>>, + + // The first 8 FP/Vector arguments are passed in XMM registers. + CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], + CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>>, + + // The first 8 MMX vector arguments are passed in GPRs. + CCIfType<[v8i8, v4i16, v2i32, v1i64], + CCAssignToReg<[RDI, RSI, RDX, RCX, R8]>>, + + // The 'nest' parameter, if any, is passed in R10. + CCIfNest>, + + // Integer/FP values get stored in stack slots that are 8 bytes in size and + // 8-byte aligned if there are no more registers to hold them. + CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>, + + // Vectors get 16-byte stack slots that are 16-byte aligned. + CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCAssignToStack<16, 16>>, + + // __m64 vectors get 8-byte stack slots that are 8-byte aligned. + CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToStack<8, 8>> +]>; + //===----------------------------------------------------------------------===// // X86 C Calling Convention @@ -173,6 +207,22 @@ CCDelegateTo ]>; +/// Same as C calling convention up to nonfree ECX which is used for storing +/// potential pointer to tail called function +def CC_X86_32_TailCall : CallingConv<[ + // Promote i8/i16 arguments to i32. + CCIfType<[i8, i16], CCPromoteToType>, + + // The 'nest' parameter, if any, is passed in ECX. + CCIfNest>, + + // The first 3 integer arguments, if marked 'inreg' and if the call is not + // a vararg call, are passed in integer registers. + CCIfNotVarArg>>>, + + // Otherwise, same as everything else. + CCDelegateTo +]>; def CC_X86_32_FastCall : CallingConv<[ // Promote i8/i16 arguments to i32. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=42870&r1=42869&r2=42870&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Oct 11 14:40:01 2007 @@ -32,6 +32,8 @@ #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" #include "llvm/Target/TargetOptions.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ParameterAttributes.h" @@ -43,6 +45,7 @@ X86ScalarSSEf64 = Subtarget->hasSSE2(); X86ScalarSSEf32 = Subtarget->hasSSE1(); X86StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP; + RegInfo = TM.getRegisterInfo(); @@ -641,6 +644,19 @@ //===----------------------------------------------------------------------===// #include "X86GenCallingConv.inc" + +/// GetPossiblePreceedingTailCall - Get preceeding X86ISD::TAILCALL node if it +/// exists skip possible ISD:TokenFactor. +static SDOperand GetPossiblePreceedingTailCall(SDOperand Chain) { + if (Chain.getOpcode()==X86ISD::TAILCALL) { + return Chain; + } else if (Chain.getOpcode()==ISD::TokenFactor) { + if (Chain.getNumOperands() && + Chain.getOperand(0).getOpcode()==X86ISD::TAILCALL) + return Chain.getOperand(0); + } + return Chain; +} /// LowerRET - Lower an ISD::RET node. SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) { @@ -651,8 +667,7 @@ bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs); CCInfo.AnalyzeReturn(Op.Val, RetCC_X86); - - + // If this is the first return lowered for this function, add the regs to the // liveout set for the function. if (DAG.getMachineFunction().liveout_empty()) { @@ -660,10 +675,38 @@ if (RVLocs[i].isRegLoc()) DAG.getMachineFunction().addLiveOut(RVLocs[i].getLocReg()); } - SDOperand Chain = Op.getOperand(0); - SDOperand Flag; + // Handle tail call return. + Chain = GetPossiblePreceedingTailCall(Chain); + if (Chain.getOpcode() == X86ISD::TAILCALL) { + SDOperand TailCall = Chain; + SDOperand TargetAddress = TailCall.getOperand(1); + SDOperand StackAdjustment = TailCall.getOperand(2); + assert ( ((TargetAddress.getOpcode() == ISD::Register && + (cast(TargetAddress)->getReg() == X86::ECX || + cast(TargetAddress)->getReg() == X86::R9)) || + TargetAddress.getOpcode() == ISD::TargetExternalSymbol || + TargetAddress.getOpcode() == ISD::TargetGlobalAddress) && + "Expecting an global address, external symbol, or register"); + assert( StackAdjustment.getOpcode() == ISD::Constant && + "Expecting a const value"); + + SmallVector Operands; + Operands.push_back(Chain.getOperand(0)); + Operands.push_back(TargetAddress); + Operands.push_back(StackAdjustment); + // Copy registers used by the call. Last operand is a flag so it is not + // copied. + for(unsigned i=3; i < TailCall.getNumOperands()-1;i++) { + Operands.push_back(Chain.getOperand(i)); + } + return DAG.getNode(X86ISD::TC_RETURN, MVT::Other, &Operands[0], Operands.size()); + } + + // Regular return. + SDOperand Flag; + // Copy the result values into the output registers. if (RVLocs.size() != 1 || !RVLocs[0].isRegLoc() || RVLocs[0].getLocReg() != X86::ST0) { @@ -684,7 +727,7 @@ if ((X86ScalarSSEf32 && RVLocs[0].getValVT()==MVT::f32) || (X86ScalarSSEf64 && RVLocs[0].getValVT()==MVT::f64)) { SDOperand MemLoc; - + // If this is a load into a scalarsse value, don't store the loaded value // back to the stack, only to reload it: just replace the scalar-sse load. if (ISD::isNON_EXTLoad(Value.Val) && @@ -784,12 +827,14 @@ //===----------------------------------------------------------------------===// -// C & StdCall Calling Convention implementation +// C & StdCall & Fast Calling Convention implementation //===----------------------------------------------------------------------===// // StdCall calling convention seems to be standard for many Windows' API // routines and around. It differs from C calling convention just a little: // callee should clean up the stack, not caller. Symbols should be also // decorated in some fancy way :) It doesn't support any vector arguments. +// For info on fast calling convention see Fast Calling Convention (tail call) +// implementation LowerX86_32FastCCCallTo. /// AddLiveIn - This helper function adds the specified physical register to the /// MachineFunction as a live in value. It also creates a corresponding virtual @@ -802,6 +847,9 @@ return VReg; } +// align stack arguments according to platform alignment needed for tail calls +unsigned GetAlignedArgumentStackSize(unsigned StackSize, SelectionDAG& DAG); + SDOperand X86TargetLowering::LowerMemArgument(SDOperand Op, SelectionDAG &DAG, const CCValAssign &VA, MachineFrameInfo *MFI, @@ -826,13 +874,17 @@ MachineFrameInfo *MFI = MF.getFrameInfo(); SDOperand Root = Op.getOperand(0); bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; - + unsigned CC = MF.getFunction()->getCallingConv(); // Assign locations to all of the incoming arguments. SmallVector ArgLocs; - CCState CCInfo(MF.getFunction()->getCallingConv(), isVarArg, + CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); - CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_32_C); - + // Check for possible tail call calling convention. + if (CC == CallingConv::Fast && PerformTailCallOpt) + CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_32_TailCall); + else + CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_32_C); + SmallVector ArgValues; unsigned LastVal = ~0U; for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { @@ -877,6 +929,9 @@ } unsigned StackSize = CCInfo.getNextStackOffset(); + // align stack specially for tail calls + if (CC==CallingConv::Fast) + StackSize = GetAlignedArgumentStackSize(StackSize,DAG); ArgValues.push_back(Root); @@ -885,7 +940,12 @@ if (isVarArg) VarArgsFrameIndex = MFI->CreateFixedObject(1, StackSize); - if (isStdCall && !isVarArg) { + // Tail call calling convention (CallingConv::Fast) does not support varargs. + assert( !(isVarArg && CC == CallingConv::Fast) && + "CallingConv::Fast does not support varargs."); + + if (isStdCall && !isVarArg && + (CC==CallingConv::Fast && PerformTailCallOpt || CC!=CallingConv::Fast)) { BytesToPopOnReturn = StackSize; // Callee pops everything.. BytesCallerReserves = 0; } else { @@ -914,17 +974,21 @@ unsigned CC) { SDOperand Chain = Op.getOperand(0); bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; - bool isTailCall = cast(Op.getOperand(3))->getValue() != 0; SDOperand Callee = Op.getOperand(4); unsigned NumOps = (Op.getNumOperands() - 5) / 2; - + // Analyze operands of the call, assigning locations to each operand. SmallVector ArgLocs; CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); - CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_32_C); + if(CC==CallingConv::Fast && PerformTailCallOpt) + CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_32_TailCall); + else + CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_32_C); // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); + if (CC==CallingConv::Fast) + NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG); Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, getPointerTy())); @@ -1023,19 +1087,21 @@ if (InFlag.Val) Ops.push_back(InFlag); - - Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, - NodeTys, &Ops[0], Ops.size()); + + Chain = DAG.getNode(X86ISD::CALL, NodeTys, &Ops[0], Ops.size()); InFlag = Chain.getValue(1); // Create the CALLSEQ_END node. unsigned NumBytesForCalleeToPush = 0; - if (CC == CallingConv::X86_StdCall) { + if (CC == CallingConv::X86_StdCall || + (CC == CallingConv::Fast && PerformTailCallOpt)) { if (isVarArg) NumBytesForCalleeToPush = isSRet ? 4 : 0; else NumBytesForCalleeToPush = NumBytes; + assert(!(isVarArg && CC==CallingConv::Fast) && + "CallingConv::Fast does not support varargs."); } else { // If this is is a call to a struct-return function, the callee // pops the hidden struct pointer, so we have to push it back. @@ -1132,7 +1198,8 @@ if (!Subtarget->isTargetCygMing() && !Subtarget->isTargetWindows()) { // Make sure the instruction takes 8n+4 bytes to make sure the start of the - // arguments and the arguments after the retaddr has been pushed are aligned. + // arguments and the arguments after the retaddr has been pushed are + // aligned. if ((StackSize & 7) == 0) StackSize += 4; } @@ -1194,7 +1261,8 @@ if (!Subtarget->isTargetCygMing() && !Subtarget->isTargetWindows()) { // Make sure the instruction takes 8n+4 bytes to make sure the start of the - // arguments and the arguments after the retaddr has been pushed are aligned. + // arguments and the arguments after the retaddr has been pushed are + // aligned. if ((NumBytes & 7) == 0) NumBytes += 4; } @@ -1292,8 +1360,8 @@ if (InFlag.Val) Ops.push_back(InFlag); - // FIXME: Do not generate X86ISD::TAILCALL for now. - Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + assert(isTailCall==false && "no tail call here"); + Chain = DAG.getNode(X86ISD::CALL, NodeTys, &Ops[0], Ops.size()); InFlag = Chain.getValue(1); @@ -1312,6 +1380,314 @@ return SDOperand(LowerCallResult(Chain, InFlag, Op.Val, CC, DAG), Op.ResNo); } +//===----------------------------------------------------------------------===// +// Fast Calling Convention (tail call) implementation +//===----------------------------------------------------------------------===// + +// Like std call, callee cleans arguments, convention except that ECX is +// reserved for storing the tail called function address. Only 2 registers are +// free for argument passing (inreg). Tail call optimization is performed +// provided: +// * tailcallopt is enabled +// * caller/callee are fastcc +// * elf/pic is disabled OR +// * elf/pic enabled + callee is in module + callee has +// visibility protected or hidden +// To ensure the stack is aligned according to platform abi pass +// tail-call-align-stack. This makes sure that argument delta is always +// multiples of stack alignment. (Dynamic linkers need this - darwin's dyld for +// example) +// If a tail called function callee has more arguments than the caller the +// caller needs to make sure that there is room to move the RETADDR to. This is +// achived by reserving an area the size of the argument delta right after the +// original REtADDR, but before the saved framepointer or the spilled registers +// e.g. caller(arg1, arg2) calls callee(arg1, arg2,arg3,arg4) +// stack layout: +// arg1 +// arg2 +// RETADDR +// [ new RETADDR +// move area ] +// (possible EBP) +// ESI +// EDI +// local1 .. + +/// GetAlignedArgumentStackSize - Make the stack size align e.g 16n + 12 aligned +/// for a 16 byte align requirement. +unsigned X86TargetLowering::GetAlignedArgumentStackSize(unsigned StackSize, + SelectionDAG& DAG) { + if (PerformTailCallOpt) { + MachineFunction &MF = DAG.getMachineFunction(); + const TargetMachine &TM = MF.getTarget(); + const TargetFrameInfo &TFI = *TM.getFrameInfo(); + unsigned StackAlignment = TFI.getStackAlignment(); + uint64_t AlignMask = StackAlignment - 1; + int64_t Offset = StackSize; + unsigned SlotSize = Subtarget->is64Bit() ? 8 : 4; + if ( (Offset & AlignMask) <= (StackAlignment - SlotSize) ) { + // Number smaller than 12 so just add the difference. + Offset += ((StackAlignment - SlotSize) - (Offset & AlignMask)); + } else { + // Mask out lower bits, add stackalignment once plus the 12 bytes. + Offset = ((~AlignMask) & Offset) + StackAlignment + + (StackAlignment-SlotSize); + } + StackSize = Offset; + } + return StackSize; +} + +/// IsEligibleForTailCallElimination - Check to see whether the next instruction +// following the call is a return. A function is eligible if caller/callee +// calling conventions match, currently only fastcc supports tail calls, and the +// function CALL is immediatly followed by a RET. +bool X86TargetLowering::IsEligibleForTailCallOptimization(SDOperand Call, + SDOperand Ret, + SelectionDAG& DAG) const { + bool IsEligible = false; + + // Check whether CALL node immediatly preceeds the RET node and whether the + // return uses the result of the node or is a void return. + if ((Ret.getNumOperands() == 1 && + (Ret.getOperand(0)== SDOperand(Call.Val,1) || + Ret.getOperand(0)== SDOperand(Call.Val,0))) || + (Ret.getOperand(0)== SDOperand(Call.Val,Call.Val->getNumValues()-1) && + Ret.getOperand(1)== SDOperand(Call.Val,0))) { + MachineFunction &MF = DAG.getMachineFunction(); + unsigned CallerCC = MF.getFunction()->getCallingConv(); + unsigned CalleeCC = cast(Call.getOperand(1))->getValue(); + if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) { + SDOperand Callee = Call.getOperand(4); + // On elf/pic %ebx needs to be livein. + if(getTargetMachine().getRelocationModel() == Reloc::PIC_ && + Subtarget->isPICStyleGOT()) { + // Can only do local tail calls with PIC. + GlobalValue * GV = 0; + GlobalAddressSDNode *G = dyn_cast(Callee); + if(G != 0 && + (GV = G->getGlobal()) && + (GV->hasHiddenVisibility() || GV->hasProtectedVisibility())) + IsEligible=true; + } else { + IsEligible=true; + } + } + } + return IsEligible; +} + +SDOperand X86TargetLowering::LowerX86_TailCallTo(SDOperand Op, + SelectionDAG &DAG, + unsigned CC) { + SDOperand Chain = Op.getOperand(0); + bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; + bool isTailCall = cast(Op.getOperand(3))->getValue() != 0; + SDOperand Callee = Op.getOperand(4); + bool is64Bit = Subtarget->is64Bit(); + + assert(isTailCall && PerformTailCallOpt && "Should only emit tail calls."); + + // Analyze operands of the call, assigning locations to each operand. + SmallVector ArgLocs; + CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); + if (is64Bit) + CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_64_TailCall); + else + CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_32_TailCall); + + + // Lower arguments at fp - stackoffset + fpdiff. + MachineFunction &MF = DAG.getMachineFunction(); + + unsigned NumBytesToBePushed = + GetAlignedArgumentStackSize(CCInfo.getNextStackOffset(), DAG); + + unsigned NumBytesCallerPushed = + MF.getInfo()->getBytesToPopOnReturn(); + int FPDiff = NumBytesCallerPushed - NumBytesToBePushed; + + // Set the delta of movement of the returnaddr stackslot. + // But only set if delta is greater than previous delta. + if (FPDiff < (MF.getInfo()->getTCReturnAddrDelta())) + MF.getInfo()->setTCReturnAddrDelta(FPDiff); + + // Adjust the ret address stack slot. + if (FPDiff) { + MVT::ValueType VT = is64Bit ? MVT::i64 : MVT::i32; + SDOperand RetAddrFrIdx = getReturnAddressFrameIndex(DAG); + RetAddrFrIdx = + DAG.getLoad(VT, DAG.getEntryNode(),RetAddrFrIdx, NULL, 0); + // Emit a store of the saved ret value to the new location. + int SlotSize = is64Bit ? 8 : 4; + int NewReturnAddrFI = + MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-SlotSize); + SDOperand NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, VT); + Chain = DAG.getStore(Chain,RetAddrFrIdx, NewRetAddrFrIdx, NULL, 0); + } + + Chain = DAG. + getCALLSEQ_START(Chain, DAG.getConstant(NumBytesToBePushed, getPointerTy())); + + SmallVector, 8> RegsToPass; + SmallVector MemOpChains; + SmallVector MemOpChains2; + SDOperand FramePtr, StackPtr; + SDOperand PtrOff; + SDOperand FIN; + int FI = 0; + + // Walk the register/memloc assignments, inserting copies/loads. Lower + // arguments first to the stack slot where they would normally - in case of a + // normal function call - be. + for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { + CCValAssign &VA = ArgLocs[i]; + SDOperand Arg = Op.getOperand(5+2*VA.getValNo()); + + // Promote the value if needed. + switch (VA.getLocInfo()) { + default: assert(0 && "Unknown loc info!"); + case CCValAssign::Full: break; + case CCValAssign::SExt: + Arg = DAG.getNode(ISD::SIGN_EXTEND, VA.getLocVT(), Arg); + break; + case CCValAssign::ZExt: + Arg = DAG.getNode(ISD::ZERO_EXTEND, VA.getLocVT(), Arg); + break; + case CCValAssign::AExt: + Arg = DAG.getNode(ISD::ANY_EXTEND, VA.getLocVT(), Arg); + break; + } + + if (VA.isRegLoc()) { + RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); + } else { + assert(VA.isMemLoc()); + if (StackPtr.Val == 0) + StackPtr = DAG.getRegister(getStackPtrReg(), getPointerTy()); + + MemOpChains.push_back(LowerMemOpCallTo(Op, DAG, StackPtr, VA, Chain, + Arg)); + } + } + + if (!MemOpChains.empty()) + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, + &MemOpChains[0], MemOpChains.size()); + + // Build a sequence of copy-to-reg nodes chained together with token chain + // and flag operands which copy the outgoing args into registers. + SDOperand InFlag; + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { + Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second, + InFlag); + InFlag = Chain.getValue(1); + } + InFlag = SDOperand(); + // Copy from stack slots to stack slot of a tail called function. This needs + // to be done because if we would lower the arguments directly to their real + // stack slot we might end up overwriting each other. + // TODO: To make this more efficient (sometimes saving a store/load) we could + // analyse the arguments and emit this store/load/store sequence only for + // arguments which would be overwritten otherwise. + for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { + CCValAssign &VA = ArgLocs[i]; + if (!VA.isRegLoc()) { + SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo()); + unsigned Flags = cast(FlagsOp)->getValue(); + + // Get source stack slot. + SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); + // Create frame index. + int32_t Offset = VA.getLocMemOffset()+FPDiff; + uint32_t OpSize = (MVT::getSizeInBits(VA.getLocVT())+7)/8; + FI = MF.getFrameInfo()->CreateFixedObject(OpSize, Offset); + FIN = DAG.getFrameIndex(FI, MVT::i32); + if (Flags & ISD::ParamFlags::ByVal) { + // Copy relative to framepointer. + unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >> + ISD::ParamFlags::ByValAlignOffs); + + unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >> + ISD::ParamFlags::ByValSizeOffs; + + SDOperand AlignNode = DAG.getConstant(Align, MVT::i32); + SDOperand SizeNode = DAG.getConstant(Size, MVT::i32); + // Copy relative to framepointer. + MemOpChains2.push_back(DAG.getNode(ISD::MEMCPY, MVT::Other, Chain, FIN, + PtrOff, SizeNode, AlignNode)); + } else { + SDOperand LoadedArg = DAG.getLoad(VA.getValVT(), Chain, PtrOff, NULL,0); + // Store relative to framepointer. + MemOpChains2.push_back(DAG.getStore(Chain, LoadedArg, FIN, NULL, 0)); + } + } + } + + if (!MemOpChains2.empty()) + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, + &MemOpChains2[0], MemOpChains.size()); + + // ELF / PIC requires GOT in the EBX register before function calls via PLT + // GOT pointer. + // Does not work with tail call since ebx is not restored correctly by + // tailcaller. TODO: at least for x86 - verify for x86-64 + + // If the callee is a GlobalAddress node (quite common, every direct call is) + // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. + if (GlobalAddressSDNode *G = dyn_cast(Callee)) { + // We should use extra load for direct calls to dllimported functions in + // non-JIT mode. + if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(), + getTargetMachine(), true)) + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy()); + } else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) + Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy()); + else { + assert(Callee.getOpcode() == ISD::LOAD && + "Function destination must be loaded into virtual register"); + unsigned Opc = is64Bit ? X86::R9 : X86::ECX; + + Chain = DAG.getCopyToReg(Chain, + DAG.getRegister(Opc, getPointerTy()) , + Callee,InFlag); + Callee = DAG.getRegister(Opc, getPointerTy()); + // Add register as live out. + DAG.getMachineFunction().addLiveOut(Opc); + } + + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SmallVector Ops; + + Ops.push_back(Chain); + Ops.push_back(DAG.getConstant(NumBytesToBePushed, getPointerTy())); + Ops.push_back(DAG.getConstant(0, getPointerTy())); + if (InFlag.Val) + Ops.push_back(InFlag); + Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size()); + InFlag = Chain.getValue(1); + + // Returns a chain & a flag for retval copy to use. + NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + Ops.clear(); + Ops.push_back(Chain); + Ops.push_back(Callee); + Ops.push_back(DAG.getConstant(FPDiff, MVT::i32)); + // Add argument registers to the end of the list so that they are known live + // into the call. + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) + Ops.push_back(DAG.getRegister(RegsToPass[i].first, + RegsToPass[i].second.getValueType())); + if (InFlag.Val) + Ops.push_back(InFlag); + assert(InFlag.Val && + "Flag must be set. Depend on flag being set in LowerRET"); + Chain = DAG.getNode(X86ISD::TAILCALL, + Op.Val->getVTList(), &Ops[0], Ops.size()); + + return SDOperand(Chain.Val, Op.ResNo); +} //===----------------------------------------------------------------------===// // X86-64 C Calling Convention implementation @@ -1323,6 +1699,7 @@ MachineFrameInfo *MFI = MF.getFrameInfo(); SDOperand Root = Op.getOperand(0); bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; + unsigned CC= MF.getFunction()->getCallingConv(); static const unsigned GPR64ArgRegs[] = { X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8, X86::R9 @@ -1335,9 +1712,12 @@ // Assign locations to all of the incoming arguments. SmallVector ArgLocs; - CCState CCInfo(MF.getFunction()->getCallingConv(), isVarArg, + CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); - CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_64_C); + if (CC == CallingConv::Fast && PerformTailCallOpt) + CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_64_TailCall); + else + CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_64_C); SmallVector ArgValues; unsigned LastVal = ~0U; @@ -1398,10 +1778,14 @@ } unsigned StackSize = CCInfo.getNextStackOffset(); + if (CC==CallingConv::Fast) + StackSize =GetAlignedArgumentStackSize(StackSize, DAG); // If the function takes variable number of arguments, make a frame index for // the start of the first vararg value... for expansion of llvm.va_start. if (isVarArg) { + assert(CC!=CallingConv::Fast + && "Var arg not supported with calling convention fastcc"); unsigned NumIntRegs = CCInfo.getFirstUnallocated(GPR64ArgRegs, 6); unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs, 8); @@ -1446,10 +1830,14 @@ } ArgValues.push_back(Root); - - BytesToPopOnReturn = 0; // Callee pops nothing. - BytesCallerReserves = StackSize; - + // Tail call convention (fastcc) needs callee pop. + if (CC == CallingConv::Fast && PerformTailCallOpt){ + BytesToPopOnReturn = StackSize; // Callee pops everything. + BytesCallerReserves = 0; + } else { + BytesToPopOnReturn = 0; // Callee pops nothing. + BytesCallerReserves = StackSize; + } X86MachineFunctionInfo *FuncInfo = MF.getInfo(); FuncInfo->setBytesToPopOnReturn(BytesToPopOnReturn); @@ -1463,16 +1851,21 @@ unsigned CC) { SDOperand Chain = Op.getOperand(0); bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; - bool isTailCall = cast(Op.getOperand(3))->getValue() != 0; SDOperand Callee = Op.getOperand(4); // Analyze operands of the call, assigning locations to each operand. SmallVector ArgLocs; CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); - CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_64_C); + if (CC==CallingConv::Fast) + CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_64_TailCall); + else + CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_64_C); // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); + if (CC == CallingConv::Fast) + NumBytes = GetAlignedArgumentStackSize(NumBytes,DAG); + Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, getPointerTy())); SmallVector, 8> RegsToPass; @@ -1526,6 +1919,9 @@ } if (isVarArg) { + assert ( CallingConv::Fast != CC && + "Var args not supported with calling convention fastcc"); + // From AMD64 ABI document: // For calls that may call functions that use varargs or stdargs // (prototype-less calls or calls to functions containing ellipsis (...) in @@ -1574,17 +1970,22 @@ if (InFlag.Val) Ops.push_back(InFlag); - // FIXME: Do not generate X86ISD::TAILCALL for now. - Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + Chain = DAG.getNode(X86ISD::CALL, NodeTys, &Ops[0], Ops.size()); InFlag = Chain.getValue(1); - + int NumBytesForCalleeToPush = 0; + if (CC==CallingConv::Fast) { + NumBytesForCalleeToPush = NumBytes; // Callee pops everything + + } else { + NumBytesForCalleeToPush = 0; // Callee pops nothing. + } // Returns a flag for retval copy to use. NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); Ops.clear(); Ops.push_back(Chain); Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); - Ops.push_back(DAG.getConstant(0, getPointerTy())); + Ops.push_back(DAG.getConstant(NumBytesForCalleeToPush, getPointerTy())); Ops.push_back(InFlag); Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size()); InFlag = Chain.getValue(1); @@ -3106,10 +3507,14 @@ // SHUFPS the element to the lowest double word, then movss. MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4); SmallVector IdxVec; - IdxVec.push_back(DAG.getConstant(Idx, MVT::getVectorElementType(MaskVT))); - IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT))); - IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT))); - IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT))); + IdxVec. + push_back(DAG.getConstant(Idx, MVT::getVectorElementType(MaskVT))); + IdxVec. + push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT))); + IdxVec. + push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT))); + IdxVec. + push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT))); SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &IdxVec[0], IdxVec.size()); Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(), @@ -3128,7 +3533,8 @@ MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4); SmallVector IdxVec; IdxVec.push_back(DAG.getConstant(1, MVT::getVectorElementType(MaskVT))); - IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT))); + IdxVec. + push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT))); SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &IdxVec[0], IdxVec.size()); Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(), @@ -3777,17 +4183,23 @@ } SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { - unsigned CallingConv= cast(Op.getOperand(1))->getValue(); + unsigned CallingConv = cast(Op.getOperand(1))->getValue(); + bool isTailCall = cast(Op.getOperand(3))->getValue() != 0; - if (Subtarget->is64Bit()) - return LowerX86_64CCCCallTo(Op, DAG, CallingConv); + if (Subtarget->is64Bit()) + if(CallingConv==CallingConv::Fast && isTailCall && PerformTailCallOpt) + return LowerX86_TailCallTo(Op, DAG, CallingConv); + else + return LowerX86_64CCCCallTo(Op, DAG, CallingConv); else switch (CallingConv) { default: assert(0 && "Unsupported calling convention"); case CallingConv::Fast: - // TODO: Implement fastcc - // Falls through + if (isTailCall && PerformTailCallOpt) + return LowerX86_TailCallTo(Op, DAG, CallingConv); + else + return LowerCCCCallTo(Op,DAG, CallingConv); case CallingConv::C: case CallingConv::X86_StdCall: return LowerCCCCallTo(Op, DAG, CallingConv); @@ -3855,8 +4267,7 @@ default: assert(0 && "Unsupported calling convention"); case CallingConv::Fast: - // TODO: implement fastcc. - + return LowerCCCArguments(Op,DAG, true); // Falls through case CallingConv::C: return LowerCCCArguments(Op, DAG); @@ -4176,7 +4587,8 @@ SDOperand TheOp = Op.getOperand(0); SDOperand rd = DAG.getNode(X86ISD::RDTSC_DAG, Tys, &TheOp, 1); if (Subtarget->is64Bit()) { - SDOperand Copy1 = DAG.getCopyFromReg(rd, X86::RAX, MVT::i64, rd.getValue(1)); + SDOperand Copy1 = + DAG.getCopyFromReg(rd, X86::RAX, MVT::i64, rd.getValue(1)); SDOperand Copy2 = DAG.getCopyFromReg(Copy1.getValue(1), X86::RDX, MVT::i64, Copy1.getValue(2)); SDOperand Tmp = DAG.getNode(ISD::SHL, MVT::i64, Copy2, @@ -4612,6 +5024,7 @@ case X86ISD::TLSADDR: return "X86ISD::TLSADDR"; case X86ISD::THREAD_POINTER: return "X86ISD::THREAD_POINTER"; case X86ISD::EH_RETURN: return "X86ISD::EH_RETURN"; + case X86ISD::TC_RETURN: return "X86ISD::TC_RETURN"; } } @@ -4885,7 +5298,7 @@ i %= NumElems; if (V.getOpcode() == ISD::SCALAR_TO_VECTOR) { return (i == 0) - ? V.getOperand(0) : DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(VT)); + ? V.getOperand(0) : DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(VT)); } else if (V.getOpcode() == ISD::VECTOR_SHUFFLE) { SDOperand Idx = PermMask.getOperand(i); if (Idx.getOpcode() == ISD::UNDEF) Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=42870&r1=42869&r2=42870&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Thu Oct 11 14:40:01 2007 @@ -181,7 +181,14 @@ TLSADDR, THREAD_POINTER, // Exception Handling helpers - EH_RETURN + EH_RETURN, + + // tail call return + // oeprand #0 chain + // operand #1 callee (register or absolute) + // operand #2 stack adjustment + // operand #3 optional in flag + TC_RETURN }; } @@ -285,6 +292,7 @@ unsigned VarArgsFPOffset; // X86-64 vararg func fp reg offset. int BytesToPopOnReturn; // Number of arg bytes ret should pop. int BytesCallerReserves; // Number of arg bytes caller makes. + public: explicit X86TargetLowering(TargetMachine &TM); @@ -364,6 +372,14 @@ virtual bool isVectorClearMaskLegal(std::vector &BVOps, MVT::ValueType EVT, SelectionDAG &DAG) const; + + /// IsEligibleForTailCallOptimization - Check whether the call is eligible + /// for tail call optimization. Target which want to do tail call + /// optimization should implement this function. + virtual bool IsEligibleForTailCallOptimization(SDOperand Call, + SDOperand Ret, + SelectionDAG &DAG) const; + private: /// Subtarget - Keep a pointer to the X86Subtarget around so that we can /// make the right decision when generating code for different targets. @@ -372,7 +388,7 @@ /// X86StackPtr - X86 physical register used as stack ptr. unsigned X86StackPtr; - + /// X86ScalarSSEf32, X86ScalarSSEf64 - Select between SSE or x87 /// floating point ops. /// When SSE is available, use it for f32 operations. @@ -402,6 +418,10 @@ SDOperand LowerX86_64CCCArguments(SDOperand Op, SelectionDAG &DAG); SDOperand LowerX86_64CCCCallTo(SDOperand Op, SelectionDAG &DAG,unsigned CC); + // fast calling convention (tail call) implementation for 32/64bit + SDOperand LowerX86_TailCallTo(SDOperand Op, + SelectionDAG & DAG, unsigned CC); + unsigned GetAlignedArgumentStackSize(unsigned StackSize, SelectionDAG &DAG); // Fast and FastCall Calling Convention implementation. SDOperand LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG); SDOperand LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC); Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=42870&r1=42869&r2=42870&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Thu Oct 11 14:40:01 2007 @@ -706,6 +706,8 @@ if (MBB.empty()) return false; switch (MBB.back().getOpcode()) { + case X86::TCRETURNri: + case X86::TCRETURNdi: case X86::RET: // Return. case X86::RETI: case X86::TAILJMPd: Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=42870&r1=42869&r2=42870&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Oct 11 14:40:01 2007 @@ -55,6 +55,8 @@ def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>; +def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>; + def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>; def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>; @@ -73,7 +75,7 @@ [SDNPHasChain, SDNPOutFlag]>; def X86callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; def X86call : SDNode<"X86ISD::CALL", SDT_X86Call, [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>; @@ -99,6 +101,8 @@ def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET, [SDNPHasChain]>; +def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET, + [SDNPHasChain, SDNPOptInFlag]>; //===----------------------------------------------------------------------===// // X86 Operand Definitions. @@ -356,15 +360,30 @@ } // Tail call stuff. + +def TAILCALL : I<0, Pseudo, (outs), (ins ), + "#TAILCALL", + []>; + +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in +def TCRETURNdi : I<0, Pseudo, (outs), (ins i32imm:$dst, i32imm:$offset), + "#TC_RETURN $dst $offset", + []>; + let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in - def TAILJMPd : IBr<0xE9, (ins i32imm:$dst), "jmp\t${dst:call} # TAIL CALL", +def TCRETURNri : I<0, Pseudo, (outs), (ins GR32:$dst, i32imm:$offset), + "#TC_RETURN $dst $offset", []>; + let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in - def TAILJMPr : I<0xFF, MRM4r, (outs), (ins GR32:$dst), "jmp\t{*}$dst # TAIL CALL", + def TAILJMPd : IBr<0xE9, (ins i32imm:$dst), "jmp\t${dst:call} # TAILCALL", []>; let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in + def TAILJMPr : I<0xFF, MRM4r, (outs), (ins GR32:$dst), "jmp{l}\t{*}$dst # TAILCALL", + []>; +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in def TAILJMPm : I<0xFF, MRM4m, (outs), (ins i32mem:$dst), - "jmp\t{*}$dst # TAIL CALL", []>; + "jmp\t{*}$dst # TAILCALL", []>; //===----------------------------------------------------------------------===// // Miscellaneous Instructions... @@ -2507,13 +2526,23 @@ (MOV32mi addr:$dst, texternalsym:$src)>; // Calls +// tailcall stuff def : Pat<(X86tailcall GR32:$dst), - (CALL32r GR32:$dst)>; + (TAILCALL)>; def : Pat<(X86tailcall (i32 tglobaladdr:$dst)), - (CALLpcrel32 tglobaladdr:$dst)>; + (TAILCALL)>; def : Pat<(X86tailcall (i32 texternalsym:$dst)), - (CALLpcrel32 texternalsym:$dst)>; + (TAILCALL)>; + +def : Pat<(X86tcret GR32:$dst, imm:$off), + (TCRETURNri GR32:$dst, imm:$off)>; + +def : Pat<(X86tcret (i32 tglobaladdr:$dst), imm:$off), + (TCRETURNdi texternalsym:$dst, imm:$off)>; + +def : Pat<(X86tcret (i32 texternalsym:$dst), imm:$off), + (TCRETURNdi texternalsym:$dst, imm:$off)>; def : Pat<(X86call (i32 tglobaladdr:$dst)), (CALLpcrel32 tglobaladdr:$dst)>; Modified: llvm/trunk/lib/Target/X86/X86InstrX86-64.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrX86-64.td?rev=42870&r1=42869&r2=42870&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrX86-64.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrX86-64.td Thu Oct 11 14:40:01 2007 @@ -102,6 +102,23 @@ "call\t{*}$dst", []>; } + + +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in +def TCRETURNdi64 : I<0, Pseudo, (outs), (ins i64imm:$dst, i32imm:$offset), + "#TC_RETURN $dst $offset", + []>; + +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in +def TCRETURNri64 : I<0, Pseudo, (outs), (ins GR64:$dst, i32imm:$offset), + "#TC_RETURN $dst $offset", + []>; + + +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in + def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst # TAILCALL", + []>; + // Branches let isBranch = 1, isTerminator = 1, isBarrier = 1 in { def JMP64r : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst", @@ -1105,6 +1122,24 @@ def : Pat<(X86tailcall GR64:$dst), (CALL64r GR64:$dst)>; + +// tailcall stuff +def : Pat<(X86tailcall GR32:$dst), + (TAILCALL)>; +def : Pat<(X86tailcall (i64 tglobaladdr:$dst)), + (TAILCALL)>; +def : Pat<(X86tailcall (i64 texternalsym:$dst)), + (TAILCALL)>; + +def : Pat<(X86tcret GR64:$dst, imm:$off), + (TCRETURNri64 GR64:$dst, imm:$off)>; + +def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off), + (TCRETURNdi64 texternalsym:$dst, imm:$off)>; + +def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off), + (TCRETURNdi64 texternalsym:$dst, imm:$off)>; + // Comparisons. // TEST R,R is smaller than CMP R,0 Modified: llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h?rev=42870&r1=42869&r2=42870&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h Thu Oct 11 14:40:01 2007 @@ -47,18 +47,26 @@ // FrameIndex for return slot. int ReturnAddrIndex; + + // Delta the ReturnAddr stack slot is moved + // Used for creating an area before the register spill area on the stack + // the returnaddr can be savely move to this area + int TailCallReturnAddrDelta; + public: X86MachineFunctionInfo() : ForceFramePointer(false), CalleeSavedFrameSize(0), BytesToPopOnReturn(0), DecorationStyle(None), - ReturnAddrIndex(0) {} + ReturnAddrIndex(0), + TailCallReturnAddrDelta(0){} X86MachineFunctionInfo(MachineFunction &MF) : ForceFramePointer(false), CalleeSavedFrameSize(0), BytesToPopOnReturn(0), DecorationStyle(None), - ReturnAddrIndex(0) {} + ReturnAddrIndex(0), + TailCallReturnAddrDelta(0) {} bool getForceFramePointer() const { return ForceFramePointer;} void setForceFramePointer(bool forceFP) { ForceFramePointer = forceFP; } @@ -74,6 +82,9 @@ int getRAIndex() const { return ReturnAddrIndex; } void setRAIndex(int Index) { ReturnAddrIndex = Index; } + + int getTCReturnAddrDelta() const { return TailCallReturnAddrDelta; } + void setTCReturnAddrDelta(int delta) {TailCallReturnAddrDelta = delta;} }; } // End llvm namespace Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=42870&r1=42869&r2=42870&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Thu Oct 11 14:40:01 2007 @@ -1436,18 +1436,42 @@ if (!hasFP(MF)) Offset += MF.getFrameInfo()->getStackSize(); - else + else { Offset += SlotSize; // Skip the saved EBP - + // Skip the RETADDR move area + X86MachineFunctionInfo *X86FI = MF.getInfo(); + int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); + if (TailCallReturnAddrDelta < 0) Offset -= TailCallReturnAddrDelta; + } + MI.getOperand(i+3).ChangeToImmediate(Offset); } void X86RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) const{ + X86MachineFunctionInfo *X86FI = MF.getInfo(); + int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); + if (TailCallReturnAddrDelta < 0) { + // create RETURNADDR area + // arg + // arg + // RETADDR + // { ... + // RETADDR area + // ... + // } + // [EBP] + MF.getFrameInfo()-> + CreateFixedObject(-TailCallReturnAddrDelta, + (-1*SlotSize)+TailCallReturnAddrDelta); + } if (hasFP(MF)) { + assert((TailCallReturnAddrDelta <= 0) && + "The Delta should always be zero or negative"); // Create a frame entry for the EBP register that must be saved. int FrameIdx = MF.getFrameInfo()->CreateFixedObject(SlotSize, - (int)SlotSize * -2); + (int)SlotSize * -2+ + TailCallReturnAddrDelta); assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() && "Slot for EBP register must be last in order to be found!"); } @@ -1530,6 +1554,41 @@ } } +/// mergeSPUpdates - Checks the instruction before/after the passed +/// instruction. If it is an ADD/SUB instruction it is deleted +/// argument and the stack adjustment is returned as a positive value for ADD +/// and a negative for SUB. +static int mergeSPUpdates(MachineBasicBlock &MBB, + MachineBasicBlock::iterator &MBBI, + unsigned StackPtr, + bool doMergeWithPrevious) { + + if ((doMergeWithPrevious && MBBI == MBB.begin()) || + (!doMergeWithPrevious && MBBI == MBB.end())) + return 0; + + int Offset = 0; + + MachineBasicBlock::iterator PI = doMergeWithPrevious ? prior(MBBI) : MBBI; + MachineBasicBlock::iterator NI = doMergeWithPrevious ? 0 : next(MBBI); + unsigned Opc = PI->getOpcode(); + if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || + Opc == X86::ADD32ri || Opc == X86::ADD32ri8) && + PI->getOperand(0).getReg() == StackPtr){ + Offset += PI->getOperand(2).getImm(); + MBB.erase(PI); + if (!doMergeWithPrevious) MBBI = NI; + } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || + Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && + PI->getOperand(0).getReg() == StackPtr) { + Offset -= PI->getOperand(2).getImm(); + MBB.erase(PI); + if (!doMergeWithPrevious) MBBI = NI; + } + + return Offset; +} + void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB MachineFrameInfo *MFI = MF.getFrameInfo(); @@ -1543,10 +1602,23 @@ // Prepare for frame info. unsigned FrameLabelId = 0; - // Get the number of bytes to allocate from the FrameInfo + // Get the number of bytes to allocate from the FrameInfo. uint64_t StackSize = MFI->getStackSize(); + // Add RETADDR move area to callee saved frame size. + int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); + if (TailCallReturnAddrDelta < 0) + X86FI->setCalleeSavedFrameSize( + X86FI->getCalleeSavedFrameSize() +(-TailCallReturnAddrDelta)); uint64_t NumBytes = StackSize - X86FI->getCalleeSavedFrameSize(); + // Insert stack pointer adjustment for later moving of return addr. Only + // applies to tail call optimized functions where the callee argument stack + // size is bigger than the callers. + if (TailCallReturnAddrDelta < 0) { + BuildMI(MBB, MBBI, TII.get(Is64Bit? X86::SUB64ri32 : X86::SUB32ri), + StackPtr).addReg(StackPtr).addImm(-TailCallReturnAddrDelta); + } + if (hasFP(MF)) { // Get the offset of the stack slot for the EBP register... which is // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. @@ -1615,6 +1687,10 @@ MBB.insert(MBBI, MI); } } else { + // If there is an SUB32ri of ESP immediately before this instruction, + // merge the two. This can be the case when tail call elimination is + // enabled and the callee has more arguments then the caller. + NumBytes -= mergeSPUpdates(MBB, MBBI, StackPtr, true); // If there is an ADD32ri or SUB32ri of ESP immediately after this // instruction, merge the two instructions. mergeSPUpdatesDown(MBB, MBBI, StackPtr, &NumBytes); @@ -1711,6 +1787,10 @@ switch (RetOpcode) { case X86::RET: case X86::RETI: + case X86::TCRETURNdi: + case X86::TCRETURNri: + case X86::TCRETURNri64: + case X86::TCRETURNdi64: case X86::EH_RETURN: case X86::TAILJMPd: case X86::TAILJMPr: @@ -1773,7 +1853,46 @@ MachineOperand &DestAddr = MBBI->getOperand(0); assert(DestAddr.isRegister() && "Offset should be in register!"); BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),StackPtr). - addReg(DestAddr.getReg()); + addReg(DestAddr.getReg()); + // Tail call return: adjust the stack pointer and jump to callee + } else if (RetOpcode == X86::TCRETURNri || RetOpcode == X86::TCRETURNdi || + RetOpcode== X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64) { + MBBI = prior(MBB.end()); + MachineOperand &JumpTarget = MBBI->getOperand(0); + MachineOperand &StackAdjust = MBBI->getOperand(1); + assert( StackAdjust.isImmediate() && "Expecting immediate value."); + + // Adjust stack pointer. + int StackAdj = StackAdjust.getImm(); + int MaxTCDelta = X86FI->getTCReturnAddrDelta(); + int Offset = 0; + assert(MaxTCDelta <= 0 && "MaxTCDelta should never be positive"); + // Incoporate the retaddr area. + Offset = StackAdj-MaxTCDelta; + assert(Offset >= 0 && "Offset should never be negative"); + if (Offset) { + // Check for possible merge with preceeding ADD instruction. + Offset += mergeSPUpdates(MBB, MBBI, StackPtr, true); + emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, TII); + } + // Jump to label or value in register. + if (RetOpcode == X86::TCRETURNdi|| RetOpcode == X86::TCRETURNdi64) + BuildMI(MBB, MBBI, TII.get(X86::TAILJMPd)). + addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); + else if (RetOpcode== X86::TCRETURNri64) { + BuildMI(MBB, MBBI, TII.get(X86::TAILJMPr64), JumpTarget.getReg()); + } else + BuildMI(MBB, MBBI, TII.get(X86::TAILJMPr), JumpTarget.getReg()); + // Delete the pseudo instruction TCRETURN. + MBB.erase(MBBI); + } else if ((RetOpcode == X86::RET || RetOpcode == X86::RETI) && + (X86FI->getTCReturnAddrDelta() < 0)) { + // Add the return addr area delta back since we are not tail calling. + int delta = -1*X86FI->getTCReturnAddrDelta(); + MBBI = prior(MBB.end()); + // Check for possible merge with preceeding ADD instruction. + delta += mergeSPUpdates(MBB, MBBI, StackPtr, true); + emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, TII); } } Added: llvm/trunk/test/CodeGen/X86/tailcall1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcall1.ll?rev=42870&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/tailcall1.ll (added) +++ llvm/trunk/test/CodeGen/X86/tailcall1.ll Thu Oct 11 14:40:01 2007 @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc -tailcallopt | grep TAILCALL +define fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4) { +entry: + ret i32 %a3 +} + +define fastcc i32 @tailcaller(i32 %in1, i32 %in2) { +entry: + %tmp11 = tail call fastcc i32 @tailcallee( i32 %in1, i32 %in2, i32 %in1, i32 %in2 ) ; [#uses=1] + ret i32 %tmp11 +} Added: llvm/trunk/test/CodeGen/X86/tailcallpic1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcallpic1.ll?rev=42870&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/tailcallpic1.ll (added) +++ llvm/trunk/test/CodeGen/X86/tailcallpic1.ll Thu Oct 11 14:40:01 2007 @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | llc -tailcallopt -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep TAILCALL + +define protected fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4) { +entry: + ret i32 %a3 +} + +define fastcc i32 @tailcaller(i32 %in1, i32 %in2) { +entry: + %tmp11 = tail call fastcc i32 @tailcallee( i32 %in1, i32 %in2, i32 %in1, i32 %in2 ) ; [#uses=1] + ret i32 %tmp11 +} Added: llvm/trunk/test/CodeGen/X86/tailcallpic2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcallpic2.ll?rev=42870&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/tailcallpic2.ll (added) +++ llvm/trunk/test/CodeGen/X86/tailcallpic2.ll Thu Oct 11 14:40:01 2007 @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | llc -tailcallopt -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep -v TAILCALL + +define fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4) { +entry: + ret i32 %a3 +} + +define fastcc i32 @tailcaller(i32 %in1, i32 %in2) { +entry: + %tmp11 = tail call fastcc i32 @tailcallee( i32 %in1, i32 %in2, i32 %in1, i32 %in2 ) ; [#uses=1] + ret i32 %tmp11 +} From djg at cray.com Thu Oct 11 16:31:09 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 11 Oct 2007 16:31:09 -0500 Subject: [llvm-commits] SCEV factories Message-ID: <20071011213109.GA21991@village.us.cray.com> The attached patch changes the SCEV factory functions from being static member functions of the SCEV subclasses to being non-static member functions of the ScalarEvolution class. This will be useful for things like the FIXME comment in SE.getSignExtendExpr (renamed from SCEVSignExtendExpr::get here). A sign-extend operator with an add-recurrence operand can possibly be transformed to an add-recurrence with a sign-extended base if the ScalarEvolution object is available and knows about the trip-count of the loop. This also applies to zero-extend as well. Also, this would make it easy to eliminate the static variables in ScalarEvolution.cpp -- they could be members of ScalarEvolutionImpl, if anyone is interested. Any objections? Dan -- Dan Gohman, Cray Inc. -------------- next part -------------- Index: include/llvm/Analysis/ScalarEvolutionExpander.h =================================================================== --- include/llvm/Analysis/ScalarEvolutionExpander.h (revision 42847) +++ include/llvm/Analysis/ScalarEvolutionExpander.h (working copy) @@ -61,8 +61,8 @@ /// starts at zero and steps by one on each iteration. Value *getOrInsertCanonicalInductionVariable(const Loop *L, const Type *Ty){ assert(Ty->isInteger() && "Can only insert integer induction variables!"); - SCEVHandle H = SCEVAddRecExpr::get(SCEVUnknown::getIntegerSCEV(0, Ty), - SCEVUnknown::getIntegerSCEV(1, Ty), L); + SCEVHandle H = SE.getAddRecExpr(SE.getIntegerSCEV(0, Ty), + SE.getIntegerSCEV(1, Ty), L); return expand(H); } Index: include/llvm/Analysis/ScalarEvolution.h =================================================================== --- include/llvm/Analysis/ScalarEvolution.h (revision 42847) +++ include/llvm/Analysis/ScalarEvolution.h (working copy) @@ -27,12 +27,15 @@ #include namespace llvm { + class APInt; + class ConstantInt; class Instruction; class Type; class ConstantRange; class Loop; class LoopInfo; class SCEVHandle; + class ScalarEvolution; /// SCEV - This class represent an analyzed expression in the program. These /// are reference counted opaque objects that the client is not allowed to @@ -56,16 +59,6 @@ public: explicit SCEV(unsigned SCEVTy) : SCEVType(SCEVTy), RefCount(0) {} - /// getNegativeSCEV - Return the SCEV object corresponding to -V. - /// - static SCEVHandle getNegativeSCEV(const SCEVHandle &V); - - /// getMinusSCEV - Return LHS-RHS. - /// - static SCEVHandle getMinusSCEV(const SCEVHandle &LHS, - const SCEVHandle &RHS); - - unsigned getSCEVType() const { return SCEVType; } /// getValueRange - Return the tightest constant bounds that this value is @@ -97,7 +90,8 @@ /// returns itself. virtual SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const = 0; + const SCEVHandle &Conc, + ScalarEvolution &SE) const = 0; /// print - Print out the internal representation of this scalar to the /// specified stream. This should really only be used for debugging @@ -131,7 +125,8 @@ void print(std::ostream *OS) const { if (OS) print(*OS); } virtual SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const; + const SCEVHandle &Conc, + ScalarEvolution &SE) const; /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SCEVCouldNotCompute *S) { return true; } @@ -204,6 +199,58 @@ /// specified expression. SCEVHandle getSCEV(Value *V) const; + SCEVHandle getConstant(ConstantInt *V); + SCEVHandle getConstant(const APInt& Val); + SCEVHandle getTruncateExpr(const SCEVHandle &Op, const Type *Ty); + SCEVHandle getZeroExtendExpr(const SCEVHandle &Op, const Type *Ty); + SCEVHandle getSignExtendExpr(const SCEVHandle &Op, const Type *Ty); + SCEVHandle getAddExpr(std::vector &Ops); + SCEVHandle getAddExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) { + std::vector Ops; + Ops.push_back(LHS); + Ops.push_back(RHS); + return getAddExpr(Ops); + } + SCEVHandle getAddExpr(const SCEVHandle &Op0, const SCEVHandle &Op1, + const SCEVHandle &Op2) { + std::vector Ops; + Ops.push_back(Op0); + Ops.push_back(Op1); + Ops.push_back(Op2); + return getAddExpr(Ops); + } + SCEVHandle getMulExpr(std::vector &Ops); + SCEVHandle getMulExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) { + std::vector Ops; + Ops.push_back(LHS); + Ops.push_back(RHS); + return getMulExpr(Ops); + } + SCEVHandle getSDivExpr(const SCEVHandle &LHS, const SCEVHandle &RHS); + SCEVHandle getAddRecExpr(const SCEVHandle &Start, const SCEVHandle &Step, + const Loop *L); + SCEVHandle getAddRecExpr(std::vector &Operands, + const Loop *L); + SCEVHandle getAddRecExpr(const std::vector &Operands, + const Loop *L) { + std::vector NewOp(Operands); + return getAddRecExpr(NewOp, L); + } + SCEVHandle getUnknown(Value *V); + + /// getNegativeSCEV - Return the SCEV object corresponding to -V. + /// + SCEVHandle getNegativeSCEV(const SCEVHandle &V); + + /// getMinusSCEV - Return LHS-RHS. + /// + SCEVHandle getMinusSCEV(const SCEVHandle &LHS, + const SCEVHandle &RHS); + + /// getIntegerSCEV - Given an integer or FP type, create a constant for the + /// specified signed integer value and return a SCEV for the constant. + SCEVHandle getIntegerSCEV(int Val, const Type *Ty); + /// hasSCEV - Return true if the SCEV for this value has already been /// computed. bool hasSCEV(Value *V) const; Index: include/llvm/Analysis/ScalarEvolutionExpressions.h =================================================================== --- include/llvm/Analysis/ScalarEvolutionExpressions.h (revision 42847) +++ include/llvm/Analysis/ScalarEvolutionExpressions.h (working copy) @@ -32,16 +32,13 @@ /// SCEVConstant - This class represents a constant integer value. /// class SCEVConstant : public SCEV { + friend class ScalarEvolution; + ConstantInt *V; explicit SCEVConstant(ConstantInt *v) : SCEV(scConstant), V(v) {} virtual ~SCEVConstant(); public: - /// get method - This just gets and returns a new SCEVConstant object. - /// - static SCEVHandle get(ConstantInt *V); - static SCEVHandle get(const APInt& Val); - ConstantInt *getValue() const { return V; } /// getValueRange - Return the tightest constant bounds that this value is @@ -59,7 +56,8 @@ virtual const Type *getType() const; SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { + const SCEVHandle &Conc, + ScalarEvolution &SE) const { return this; } @@ -78,15 +76,13 @@ /// to a smaller integer value. /// class SCEVTruncateExpr : public SCEV { + friend class ScalarEvolution; + SCEVHandle Op; const Type *Ty; SCEVTruncateExpr(const SCEVHandle &op, const Type *ty); virtual ~SCEVTruncateExpr(); public: - /// get method - This just gets and returns a new SCEVTruncate object - /// - static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); - const SCEVHandle &getOperand() const { return Op; } virtual const Type *getType() const { return Ty; } @@ -99,11 +95,12 @@ } SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { - SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc); + const SCEVHandle &Conc, + ScalarEvolution &SE) const { + SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); if (H == Op) return this; - return get(H, Ty); + return SE.getTruncateExpr(H, Ty); } /// getValueRange - Return the tightest constant bounds that this value is @@ -125,15 +122,13 @@ /// integer value to a larger integer value. /// class SCEVZeroExtendExpr : public SCEV { + friend class ScalarEvolution; + SCEVHandle Op; const Type *Ty; SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty); virtual ~SCEVZeroExtendExpr(); public: - /// get method - This just gets and returns a new SCEVZeroExtend object - /// - static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); - const SCEVHandle &getOperand() const { return Op; } virtual const Type *getType() const { return Ty; } @@ -150,11 +145,12 @@ virtual ConstantRange getValueRange() const; SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { - SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc); + const SCEVHandle &Conc, + ScalarEvolution &SE) const { + SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); if (H == Op) return this; - return get(H, Ty); + return SE.getZeroExtendExpr(H, Ty); } virtual void print(std::ostream &OS) const; @@ -172,15 +168,13 @@ /// integer value to a larger integer value. /// class SCEVSignExtendExpr : public SCEV { + friend class ScalarEvolution; + SCEVHandle Op; const Type *Ty; SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty); virtual ~SCEVSignExtendExpr(); public: - /// get method - This just gets and returns a new SCEVSignExtend object - /// - static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); - const SCEVHandle &getOperand() const { return Op; } virtual const Type *getType() const { return Ty; } @@ -197,11 +191,12 @@ virtual ConstantRange getValueRange() const; SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { - SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc); + const SCEVHandle &Conc, + ScalarEvolution &SE) const { + SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); if (H == Op) return this; - return get(H, Ty); + return SE.getSignExtendExpr(H, Ty); } virtual void print(std::ostream &OS) const; @@ -220,6 +215,8 @@ /// operators. /// class SCEVCommutativeExpr : public SCEV { + friend class ScalarEvolution; + std::vector Operands; protected: @@ -264,7 +261,8 @@ } SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const; + const SCEVHandle &Conc, + ScalarEvolution &SE) const; virtual const char *getOperationStr() const = 0; @@ -285,29 +283,13 @@ /// SCEVAddExpr - This node represents an addition of some number of SCEVs. /// class SCEVAddExpr : public SCEVCommutativeExpr { + friend class ScalarEvolution; + SCEVAddExpr(const std::vector &ops) : SCEVCommutativeExpr(scAddExpr, ops) { } public: - static SCEVHandle get(std::vector &Ops); - - static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS) { - std::vector Ops; - Ops.push_back(LHS); - Ops.push_back(RHS); - return get(Ops); - } - - static SCEVHandle get(const SCEVHandle &Op0, const SCEVHandle &Op1, - const SCEVHandle &Op2) { - std::vector Ops; - Ops.push_back(Op0); - Ops.push_back(Op1); - Ops.push_back(Op2); - return get(Ops); - } - virtual const char *getOperationStr() const { return " + "; } /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -321,20 +303,13 @@ /// SCEVMulExpr - This node represents multiplication of some number of SCEVs. /// class SCEVMulExpr : public SCEVCommutativeExpr { + friend class ScalarEvolution; + SCEVMulExpr(const std::vector &ops) : SCEVCommutativeExpr(scMulExpr, ops) { } public: - static SCEVHandle get(std::vector &Ops); - - static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS) { - std::vector Ops; - Ops.push_back(LHS); - Ops.push_back(RHS); - return get(Ops); - } - virtual const char *getOperationStr() const { return " * "; } /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -349,16 +324,14 @@ /// SCEVSDivExpr - This class represents a binary signed division operation. /// class SCEVSDivExpr : public SCEV { + friend class ScalarEvolution; + SCEVHandle LHS, RHS; SCEVSDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs) : SCEV(scSDivExpr), LHS(lhs), RHS(rhs) {} virtual ~SCEVSDivExpr(); public: - /// get method - This just gets and returns a new SCEVSDiv object. - /// - static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS); - const SCEVHandle &getLHS() const { return LHS; } const SCEVHandle &getRHS() const { return RHS; } @@ -372,13 +345,14 @@ } SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { - SCEVHandle L = LHS->replaceSymbolicValuesWithConcrete(Sym, Conc); - SCEVHandle R = RHS->replaceSymbolicValuesWithConcrete(Sym, Conc); + const SCEVHandle &Conc, + ScalarEvolution &SE) const { + SCEVHandle L = LHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); + SCEVHandle R = RHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); if (L == LHS && R == RHS) return this; else - return get(L, R); + return SE.getSDivExpr(L, R); } @@ -402,6 +376,8 @@ /// All operands of an AddRec are required to be loop invariant. /// class SCEVAddRecExpr : public SCEV { + friend class ScalarEvolution; + std::vector Operands; const Loop *L; @@ -413,16 +389,6 @@ } ~SCEVAddRecExpr(); public: - static SCEVHandle get(const SCEVHandle &Start, const SCEVHandle &Step, - const Loop *); - static SCEVHandle get(std::vector &Operands, - const Loop *); - static SCEVHandle get(const std::vector &Operands, - const Loop *L) { - std::vector NewOp(Operands); - return get(NewOp, L); - } - typedef std::vector::const_iterator op_iterator; op_iterator op_begin() const { return Operands.begin(); } op_iterator op_end() const { return Operands.end(); } @@ -436,10 +402,10 @@ /// getStepRecurrence - This method constructs and returns the recurrence /// indicating how much this expression steps by. If this is a polynomial /// of degree N, it returns a chrec of degree N-1. - SCEVHandle getStepRecurrence() const { + SCEVHandle getStepRecurrence(ScalarEvolution &SE) const { if (getNumOperands() == 2) return getOperand(1); - return SCEVAddRecExpr::get(std::vector(op_begin()+1,op_end()), - getLoop()); + return SE.getAddRecExpr(std::vector(op_begin()+1,op_end()), + getLoop()); } virtual bool hasComputableLoopEvolution(const Loop *QL) const { @@ -468,7 +434,7 @@ /// evaluateAtIteration - Return the value of this chain of recurrences at /// the specified iteration number. - SCEVHandle evaluateAtIteration(SCEVHandle It) const; + SCEVHandle evaluateAtIteration(SCEVHandle It, ScalarEvolution &SE) const; /// getNumIterationsInRange - Return the number of iterations of this loop /// that produce values in the specified constant range. Another way of @@ -476,10 +442,12 @@ /// value is not in the condition, thus computing the exit count. If the /// iteration count can't be computed, an instance of SCEVCouldNotCompute is /// returned. - SCEVHandle getNumIterationsInRange(ConstantRange Range) const; + SCEVHandle getNumIterationsInRange(ConstantRange Range, + ScalarEvolution &SE) const; SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const; + const SCEVHandle &Conc, + ScalarEvolution &SE) const; virtual void print(std::ostream &OS) const; void print(std::ostream *OS) const { if (OS) print(*OS); } @@ -497,20 +465,14 @@ /// value for the analysis. /// class SCEVUnknown : public SCEV { + friend class ScalarEvolution; + Value *V; SCEVUnknown(Value *v) : SCEV(scUnknown), V(v) {} protected: ~SCEVUnknown(); public: - /// get method - For SCEVUnknown, this just gets and returns a new - /// SCEVUnknown. - static SCEVHandle get(Value *V); - - /// getIntegerSCEV - Given an integer or FP type, create a constant for the - /// specified signed integer value and return a SCEV for the constant. - static SCEVHandle getIntegerSCEV(int Val, const Type *Ty); - Value *getValue() const { return V; } virtual bool isLoopInvariant(const Loop *L) const; @@ -519,7 +481,8 @@ } SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { + const SCEVHandle &Conc, + ScalarEvolution &SE) const { if (&*Sym == this) return Conc; return this; } Index: lib/Analysis/ScalarEvolutionExpander.cpp =================================================================== --- lib/Analysis/ScalarEvolutionExpander.cpp (revision 42847) +++ lib/Analysis/ScalarEvolutionExpander.cpp (working copy) @@ -128,8 +128,8 @@ !cast(S->getStart())->getValue()->isZero()) { Value *Start = expand(S->getStart()); std::vector NewOps(S->op_begin(), S->op_end()); - NewOps[0] = SCEVUnknown::getIntegerSCEV(0, Ty); - Value *Rest = expand(SCEVAddRecExpr::get(NewOps, L)); + NewOps[0] = SE.getIntegerSCEV(0, Ty); + Value *Rest = expand(SE.getAddRecExpr(NewOps, L)); // FIXME: look for an existing add to use. return InsertBinop(Instruction::Add, Rest, Start, InsertPt); @@ -137,7 +137,7 @@ // {0,+,1} --> Insert a canonical induction variable into the loop! if (S->getNumOperands() == 2 && - S->getOperand(1) == SCEVUnknown::getIntegerSCEV(1, Ty)) { + S->getOperand(1) == SE.getIntegerSCEV(1, Ty)) { // Create and insert the PHI node for the induction variable in the // specified loop. BasicBlock *Header = L->getHeader(); @@ -200,9 +200,9 @@ // folders, then expandCodeFor the closed form. This allows the folders to // simplify the expression without having to build a bunch of special code // into this folder. - SCEVHandle IH = SCEVUnknown::get(I); // Get I as a "symbolic" SCEV. + SCEVHandle IH = SE.getUnknown(I); // Get I as a "symbolic" SCEV. - SCEVHandle V = S->evaluateAtIteration(IH); + SCEVHandle V = S->evaluateAtIteration(IH, SE); //cerr << "Evaluated: " << *this << "\n to: " << *V << "\n"; return expand(V); Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp (revision 42847) +++ lib/Analysis/ScalarEvolution.cpp (working copy) @@ -154,7 +154,8 @@ SCEVHandle SCEVCouldNotCompute:: replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { + const SCEVHandle &Conc, + ScalarEvolution &SE) const { return this; } @@ -177,14 +178,14 @@ SCEVConstants->erase(V); } -SCEVHandle SCEVConstant::get(ConstantInt *V) { +SCEVHandle ScalarEvolution::getConstant(ConstantInt *V) { SCEVConstant *&R = (*SCEVConstants)[V]; if (R == 0) R = new SCEVConstant(V); return R; } -SCEVHandle SCEVConstant::get(const APInt& Val) { - return get(ConstantInt::get(Val)); +SCEVHandle ScalarEvolution::getConstant(const APInt& Val) { + return getConstant(ConstantInt::get(Val)); } ConstantRange SCEVConstant::getValueRange() const { @@ -298,9 +299,11 @@ SCEVHandle SCEVCommutativeExpr:: replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { + const SCEVHandle &Conc, + ScalarEvolution &SE) const { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - SCEVHandle H = getOperand(i)->replaceSymbolicValuesWithConcrete(Sym, Conc); + SCEVHandle H = + getOperand(i)->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); if (H != getOperand(i)) { std::vector NewOps; NewOps.reserve(getNumOperands()); @@ -309,12 +312,12 @@ NewOps.push_back(H); for (++i; i != e; ++i) NewOps.push_back(getOperand(i)-> - replaceSymbolicValuesWithConcrete(Sym, Conc)); + replaceSymbolicValuesWithConcrete(Sym, Conc, SE)); if (isa(this)) - return SCEVAddExpr::get(NewOps); + return SE.getAddExpr(NewOps); else if (isa(this)) - return SCEVMulExpr::get(NewOps); + return SE.getMulExpr(NewOps); else assert(0 && "Unknown commutative expr!"); } @@ -355,9 +358,11 @@ SCEVHandle SCEVAddRecExpr:: replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { + const SCEVHandle &Conc, + ScalarEvolution &SE) const { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - SCEVHandle H = getOperand(i)->replaceSymbolicValuesWithConcrete(Sym, Conc); + SCEVHandle H = + getOperand(i)->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); if (H != getOperand(i)) { std::vector NewOps; NewOps.reserve(getNumOperands()); @@ -366,9 +371,9 @@ NewOps.push_back(H); for (++i; i != e; ++i) NewOps.push_back(getOperand(i)-> - replaceSymbolicValuesWithConcrete(Sym, Conc)); + replaceSymbolicValuesWithConcrete(Sym, Conc, SE)); - return get(NewOps, L); + return SE.getAddRecExpr(NewOps, L); } } return this; @@ -480,7 +485,7 @@ /// getIntegerSCEV - Given an integer or FP type, create a constant for the /// specified signed integer value and return a SCEV for the constant. -SCEVHandle SCEVUnknown::getIntegerSCEV(int Val, const Type *Ty) { +SCEVHandle ScalarEvolution::getIntegerSCEV(int Val, const Type *Ty) { Constant *C; if (Val == 0) C = Constant::getNullValue(Ty); @@ -489,42 +494,45 @@ APFloat::IEEEdouble, Val)); else C = ConstantInt::get(Ty, Val); - return SCEVUnknown::get(C); + return getUnknown(C); } /// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion of the /// input value to the specified type. If the type must be extended, it is zero /// extended. -static SCEVHandle getTruncateOrZeroExtend(const SCEVHandle &V, const Type *Ty) { +static SCEVHandle getTruncateOrZeroExtend(const SCEVHandle &V, const Type *Ty, + ScalarEvolution &SE) { const Type *SrcTy = V->getType(); assert(SrcTy->isInteger() && Ty->isInteger() && "Cannot truncate or zero extend with non-integer arguments!"); if (SrcTy->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits()) return V; // No conversion if (SrcTy->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()) - return SCEVTruncateExpr::get(V, Ty); - return SCEVZeroExtendExpr::get(V, Ty); + return SE.getTruncateExpr(V, Ty); + return SE.getZeroExtendExpr(V, Ty); } /// getNegativeSCEV - Return a SCEV corresponding to -V = -1*V /// -SCEVHandle SCEV::getNegativeSCEV(const SCEVHandle &V) { +SCEVHandle ScalarEvolution::getNegativeSCEV(const SCEVHandle &V) { if (SCEVConstant *VC = dyn_cast(V)) - return SCEVUnknown::get(ConstantExpr::getNeg(VC->getValue())); + return getUnknown(ConstantExpr::getNeg(VC->getValue())); - return SCEVMulExpr::get(V, SCEVUnknown::getIntegerSCEV(-1, V->getType())); + return getMulExpr(V, getIntegerSCEV(-1, V->getType())); } /// getMinusSCEV - Return a SCEV corresponding to LHS - RHS. /// -SCEVHandle SCEV::getMinusSCEV(const SCEVHandle &LHS, const SCEVHandle &RHS) { +SCEVHandle ScalarEvolution::getMinusSCEV(const SCEVHandle &LHS, + const SCEVHandle &RHS) { // X - Y --> X + -Y - return SCEVAddExpr::get(LHS, SCEV::getNegativeSCEV(RHS)); + return getAddExpr(LHS, getNegativeSCEV(RHS)); } /// PartialFact - Compute V!/(V-NumSteps)! -static SCEVHandle PartialFact(SCEVHandle V, unsigned NumSteps) { +static SCEVHandle PartialFact(SCEVHandle V, unsigned NumSteps, + ScalarEvolution &SE) { // Handle this case efficiently, it is common to have constant iteration // counts while computing loop exit values. if (SCEVConstant *SC = dyn_cast(V)) { @@ -532,17 +540,17 @@ APInt Result(Val.getBitWidth(), 1); for (; NumSteps; --NumSteps) Result *= Val-(NumSteps-1); - return SCEVConstant::get(Result); + return SE.getConstant(Result); } const Type *Ty = V->getType(); if (NumSteps == 0) - return SCEVUnknown::getIntegerSCEV(1, Ty); + return SE.getIntegerSCEV(1, Ty); SCEVHandle Result = V; for (unsigned i = 1; i != NumSteps; ++i) - Result = SCEVMulExpr::get(Result, SCEV::getMinusSCEV(V, - SCEVUnknown::getIntegerSCEV(i, Ty))); + Result = SE.getMulExpr(Result, SE.getMinusSCEV(V, + SE.getIntegerSCEV(i, Ty))); return Result; } @@ -557,16 +565,17 @@ /// FIXME/VERIFY: I don't trust that this is correct in the face of overflow. /// Is the binomial equation safe using modular arithmetic?? /// -SCEVHandle SCEVAddRecExpr::evaluateAtIteration(SCEVHandle It) const { +SCEVHandle SCEVAddRecExpr::evaluateAtIteration(SCEVHandle It, + ScalarEvolution &SE) const { SCEVHandle Result = getStart(); int Divisor = 1; const Type *Ty = It->getType(); for (unsigned i = 1, e = getNumOperands(); i != e; ++i) { - SCEVHandle BC = PartialFact(It, i); + SCEVHandle BC = PartialFact(It, i, SE); Divisor *= i; - SCEVHandle Val = SCEVSDivExpr::get(SCEVMulExpr::get(BC, getOperand(i)), - SCEVUnknown::getIntegerSCEV(Divisor,Ty)); - Result = SCEVAddExpr::get(Result, Val); + SCEVHandle Val = SE.getSDivExpr(SE.getMulExpr(BC, getOperand(i)), + SE.getIntegerSCEV(Divisor,Ty)); + Result = SE.getAddExpr(Result, Val); } return Result; } @@ -576,9 +585,9 @@ // SCEV Expression folder implementations //===----------------------------------------------------------------------===// -SCEVHandle SCEVTruncateExpr::get(const SCEVHandle &Op, const Type *Ty) { +SCEVHandle ScalarEvolution::getTruncateExpr(const SCEVHandle &Op, const Type *Ty) { if (SCEVConstant *SC = dyn_cast(Op)) - return SCEVUnknown::get( + return getUnknown( ConstantExpr::getTrunc(SC->getValue(), Ty)); // If the input value is a chrec scev made out of constants, truncate @@ -588,11 +597,11 @@ for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) // FIXME: This should allow truncation of other expression types! if (isa(AddRec->getOperand(i))) - Operands.push_back(get(AddRec->getOperand(i), Ty)); + Operands.push_back(getTruncateExpr(AddRec->getOperand(i), Ty)); else break; if (Operands.size() == AddRec->getNumOperands()) - return SCEVAddRecExpr::get(Operands, AddRec->getLoop()); + return getAddRecExpr(Operands, AddRec->getLoop()); } SCEVTruncateExpr *&Result = (*SCEVTruncates)[std::make_pair(Op, Ty)]; @@ -600,9 +609,9 @@ return Result; } -SCEVHandle SCEVZeroExtendExpr::get(const SCEVHandle &Op, const Type *Ty) { +SCEVHandle ScalarEvolution::getZeroExtendExpr(const SCEVHandle &Op, const Type *Ty) { if (SCEVConstant *SC = dyn_cast(Op)) - return SCEVUnknown::get( + return getUnknown( ConstantExpr::getZExt(SC->getValue(), Ty)); // FIXME: If the input value is a chrec scev, and we can prove that the value @@ -615,9 +624,9 @@ return Result; } -SCEVHandle SCEVSignExtendExpr::get(const SCEVHandle &Op, const Type *Ty) { +SCEVHandle ScalarEvolution::getSignExtendExpr(const SCEVHandle &Op, const Type *Ty) { if (SCEVConstant *SC = dyn_cast(Op)) - return SCEVUnknown::get( + return getUnknown( ConstantExpr::getSExt(SC->getValue(), Ty)); // FIXME: If the input value is a chrec scev, and we can prove that the value @@ -631,7 +640,7 @@ } // get - Get a canonical add expression, or something simpler if possible. -SCEVHandle SCEVAddExpr::get(std::vector &Ops) { +SCEVHandle ScalarEvolution::getAddExpr(std::vector &Ops) { assert(!Ops.empty() && "Cannot get empty add!"); if (Ops.size() == 1) return Ops[0]; @@ -648,7 +657,7 @@ Constant *Fold = ConstantInt::get(LHSC->getValue()->getValue() + RHSC->getValue()->getValue()); if (ConstantInt *CI = dyn_cast(Fold)) { - Ops[0] = SCEVConstant::get(CI); + Ops[0] = getConstant(CI); Ops.erase(Ops.begin()+1); // Erase the folded element if (Ops.size() == 1) return Ops[0]; LHSC = cast(Ops[0]); @@ -677,13 +686,13 @@ if (Ops[i] == Ops[i+1]) { // X + Y + Y --> X + Y*2 // Found a match, merge the two values into a multiply, and add any // remaining values to the result. - SCEVHandle Two = SCEVUnknown::getIntegerSCEV(2, Ty); - SCEVHandle Mul = SCEVMulExpr::get(Ops[i], Two); + SCEVHandle Two = getIntegerSCEV(2, Ty); + SCEVHandle Mul = getMulExpr(Ops[i], Two); if (Ops.size() == 2) return Mul; Ops.erase(Ops.begin()+i, Ops.begin()+i+2); Ops.push_back(Mul); - return SCEVAddExpr::get(Ops); + return getAddExpr(Ops); } // Now we know the first non-constant operand. Skip past any cast SCEVs. @@ -705,7 +714,7 @@ // and they are not necessarily sorted. Recurse to resort and resimplify // any operands we just aquired. if (DeletedAdd) - return get(Ops); + return getAddExpr(Ops); } // Skip over the add expression until we get to a multiply. @@ -728,11 +737,11 @@ // Y*Z term. std::vector MulOps(Mul->op_begin(), Mul->op_end()); MulOps.erase(MulOps.begin()+MulOp); - InnerMul = SCEVMulExpr::get(MulOps); + InnerMul = getMulExpr(MulOps); } - SCEVHandle One = SCEVUnknown::getIntegerSCEV(1, Ty); - SCEVHandle AddOne = SCEVAddExpr::get(InnerMul, One); - SCEVHandle OuterMul = SCEVMulExpr::get(AddOne, Ops[AddOp]); + SCEVHandle One = getIntegerSCEV(1, Ty); + SCEVHandle AddOne = getAddExpr(InnerMul, One); + SCEVHandle OuterMul = getMulExpr(AddOne, Ops[AddOp]); if (Ops.size() == 2) return OuterMul; if (AddOp < Idx) { Ops.erase(Ops.begin()+AddOp); @@ -742,7 +751,7 @@ Ops.erase(Ops.begin()+AddOp-1); } Ops.push_back(OuterMul); - return SCEVAddExpr::get(Ops); + return getAddExpr(Ops); } // Check this multiply against other multiplies being added together. @@ -760,22 +769,22 @@ if (Mul->getNumOperands() != 2) { std::vector MulOps(Mul->op_begin(), Mul->op_end()); MulOps.erase(MulOps.begin()+MulOp); - InnerMul1 = SCEVMulExpr::get(MulOps); + InnerMul1 = getMulExpr(MulOps); } SCEVHandle InnerMul2 = OtherMul->getOperand(OMulOp == 0); if (OtherMul->getNumOperands() != 2) { std::vector MulOps(OtherMul->op_begin(), OtherMul->op_end()); MulOps.erase(MulOps.begin()+OMulOp); - InnerMul2 = SCEVMulExpr::get(MulOps); + InnerMul2 = getMulExpr(MulOps); } - SCEVHandle InnerMulSum = SCEVAddExpr::get(InnerMul1,InnerMul2); - SCEVHandle OuterMul = SCEVMulExpr::get(MulOpSCEV, InnerMulSum); + SCEVHandle InnerMulSum = getAddExpr(InnerMul1,InnerMul2); + SCEVHandle OuterMul = getMulExpr(MulOpSCEV, InnerMulSum); if (Ops.size() == 2) return OuterMul; Ops.erase(Ops.begin()+Idx); Ops.erase(Ops.begin()+OtherMulIdx-1); Ops.push_back(OuterMul); - return SCEVAddExpr::get(Ops); + return getAddExpr(Ops); } } } @@ -806,9 +815,9 @@ LIOps.push_back(AddRec->getStart()); std::vector AddRecOps(AddRec->op_begin(), AddRec->op_end()); - AddRecOps[0] = SCEVAddExpr::get(LIOps); + AddRecOps[0] = getAddExpr(LIOps); - SCEVHandle NewRec = SCEVAddRecExpr::get(AddRecOps, AddRec->getLoop()); + SCEVHandle NewRec = getAddRecExpr(AddRecOps, AddRec->getLoop()); // If all of the other operands were loop invariant, we are done. if (Ops.size() == 1) return NewRec; @@ -818,7 +827,7 @@ Ops[i] = NewRec; break; } - return SCEVAddExpr::get(Ops); + return getAddExpr(Ops); } // Okay, if there weren't any loop invariants to be folded, check to see if @@ -837,16 +846,16 @@ OtherAddRec->op_end()); break; } - NewOps[i] = SCEVAddExpr::get(NewOps[i], OtherAddRec->getOperand(i)); + NewOps[i] = getAddExpr(NewOps[i], OtherAddRec->getOperand(i)); } - SCEVHandle NewAddRec = SCEVAddRecExpr::get(NewOps, AddRec->getLoop()); + SCEVHandle NewAddRec = getAddRecExpr(NewOps, AddRec->getLoop()); if (Ops.size() == 2) return NewAddRec; Ops.erase(Ops.begin()+Idx); Ops.erase(Ops.begin()+OtherIdx-1); Ops.push_back(NewAddRec); - return SCEVAddExpr::get(Ops); + return getAddExpr(Ops); } } @@ -864,7 +873,7 @@ } -SCEVHandle SCEVMulExpr::get(std::vector &Ops) { +SCEVHandle ScalarEvolution::getMulExpr(std::vector &Ops) { assert(!Ops.empty() && "Cannot get empty mul!"); // Sort by complexity, this groups all similar expression types together. @@ -879,8 +888,8 @@ if (SCEVAddExpr *Add = dyn_cast(Ops[1])) if (Add->getNumOperands() == 2 && isa(Add->getOperand(0))) - return SCEVAddExpr::get(SCEVMulExpr::get(LHSC, Add->getOperand(0)), - SCEVMulExpr::get(LHSC, Add->getOperand(1))); + return getAddExpr(getMulExpr(LHSC, Add->getOperand(0)), + getMulExpr(LHSC, Add->getOperand(1))); ++Idx; @@ -889,7 +898,7 @@ Constant *Fold = ConstantInt::get(LHSC->getValue()->getValue() * RHSC->getValue()->getValue()); if (ConstantInt *CI = dyn_cast(Fold)) { - Ops[0] = SCEVConstant::get(CI); + Ops[0] = getConstant(CI); Ops.erase(Ops.begin()+1); // Erase the folded element if (Ops.size() == 1) return Ops[0]; LHSC = cast(Ops[0]); @@ -933,7 +942,7 @@ // and they are not necessarily sorted. Recurse to resort and resimplify // any operands we just aquired. if (DeletedMul) - return get(Ops); + return getMulExpr(Ops); } // If there are any add recurrences in the operands list, see if any other @@ -963,16 +972,16 @@ if (LIOps.size() == 1) { SCEV *Scale = LIOps[0]; for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) - NewOps.push_back(SCEVMulExpr::get(Scale, AddRec->getOperand(i))); + NewOps.push_back(getMulExpr(Scale, AddRec->getOperand(i))); } else { for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) { std::vector MulOps(LIOps); MulOps.push_back(AddRec->getOperand(i)); - NewOps.push_back(SCEVMulExpr::get(MulOps)); + NewOps.push_back(getMulExpr(MulOps)); } } - SCEVHandle NewRec = SCEVAddRecExpr::get(NewOps, AddRec->getLoop()); + SCEVHandle NewRec = getAddRecExpr(NewOps, AddRec->getLoop()); // If all of the other operands were loop invariant, we are done. if (Ops.size() == 1) return NewRec; @@ -983,7 +992,7 @@ Ops[i] = NewRec; break; } - return SCEVMulExpr::get(Ops); + return getMulExpr(Ops); } // Okay, if there weren't any loop invariants to be folded, check to see if @@ -996,21 +1005,21 @@ if (AddRec->getLoop() == OtherAddRec->getLoop()) { // F * G --> {A,+,B} * {C,+,D} --> {A*C,+,F*D + G*B + B*D} SCEVAddRecExpr *F = AddRec, *G = OtherAddRec; - SCEVHandle NewStart = SCEVMulExpr::get(F->getStart(), + SCEVHandle NewStart = getMulExpr(F->getStart(), G->getStart()); - SCEVHandle B = F->getStepRecurrence(); - SCEVHandle D = G->getStepRecurrence(); - SCEVHandle NewStep = SCEVAddExpr::get(SCEVMulExpr::get(F, D), - SCEVMulExpr::get(G, B), - SCEVMulExpr::get(B, D)); - SCEVHandle NewAddRec = SCEVAddRecExpr::get(NewStart, NewStep, - F->getLoop()); + SCEVHandle B = F->getStepRecurrence(*this); + SCEVHandle D = G->getStepRecurrence(*this); + SCEVHandle NewStep = getAddExpr(getMulExpr(F, D), + getMulExpr(G, B), + getMulExpr(B, D)); + SCEVHandle NewAddRec = getAddRecExpr(NewStart, NewStep, + F->getLoop()); if (Ops.size() == 2) return NewAddRec; Ops.erase(Ops.begin()+Idx); Ops.erase(Ops.begin()+OtherIdx-1); Ops.push_back(NewAddRec); - return SCEVMulExpr::get(Ops); + return getMulExpr(Ops); } } @@ -1028,17 +1037,17 @@ return Result; } -SCEVHandle SCEVSDivExpr::get(const SCEVHandle &LHS, const SCEVHandle &RHS) { +SCEVHandle ScalarEvolution::getSDivExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) { if (SCEVConstant *RHSC = dyn_cast(RHS)) { if (RHSC->getValue()->equalsInt(1)) return LHS; // X sdiv 1 --> x if (RHSC->getValue()->isAllOnesValue()) - return SCEV::getNegativeSCEV(LHS); // X sdiv -1 --> -x + return getNegativeSCEV(LHS); // X sdiv -1 --> -x if (SCEVConstant *LHSC = dyn_cast(LHS)) { Constant *LHSCV = LHSC->getValue(); Constant *RHSCV = RHSC->getValue(); - return SCEVUnknown::get(ConstantExpr::getSDiv(LHSCV, RHSCV)); + return getUnknown(ConstantExpr::getSDiv(LHSCV, RHSCV)); } } @@ -1052,7 +1061,7 @@ /// SCEVAddRecExpr::get - Get a add recurrence expression for the /// specified loop. Simplify the expression as much as possible. -SCEVHandle SCEVAddRecExpr::get(const SCEVHandle &Start, +SCEVHandle ScalarEvolution::getAddRecExpr(const SCEVHandle &Start, const SCEVHandle &Step, const Loop *L) { std::vector Operands; Operands.push_back(Start); @@ -1060,23 +1069,23 @@ if (StepChrec->getLoop() == L) { Operands.insert(Operands.end(), StepChrec->op_begin(), StepChrec->op_end()); - return get(Operands, L); + return getAddRecExpr(Operands, L); } Operands.push_back(Step); - return get(Operands, L); + return getAddRecExpr(Operands, L); } /// SCEVAddRecExpr::get - Get a add recurrence expression for the /// specified loop. Simplify the expression as much as possible. -SCEVHandle SCEVAddRecExpr::get(std::vector &Operands, +SCEVHandle ScalarEvolution::getAddRecExpr(std::vector &Operands, const Loop *L) { if (Operands.size() == 1) return Operands[0]; if (SCEVConstant *StepC = dyn_cast(Operands.back())) if (StepC->getValue()->isZero()) { Operands.pop_back(); - return get(Operands, L); // { X,+,0 } --> X + return getAddRecExpr(Operands, L); // { X,+,0 } --> X } SCEVAddRecExpr *&Result = @@ -1086,9 +1095,9 @@ return Result; } -SCEVHandle SCEVUnknown::get(Value *V) { +SCEVHandle ScalarEvolution::getUnknown(Value *V) { if (ConstantInt *CI = dyn_cast(V)) - return SCEVConstant::get(CI); + return getConstant(CI); SCEVUnknown *&Result = (*SCEVUnknowns)[V]; if (Result == 0) Result = new SCEVUnknown(V); return Result; @@ -1104,6 +1113,9 @@ /// namespace { struct VISIBILITY_HIDDEN ScalarEvolutionsImpl { + /// SE - A reference to the public ScalarEvolution object. + ScalarEvolution &SE; + /// F - The function we are analyzing. /// Function &F; @@ -1132,8 +1144,8 @@ std::map ConstantEvolutionLoopExitValue; public: - ScalarEvolutionsImpl(Function &f, LoopInfo &li) - : F(f), LI(li), UnknownValue(new SCEVCouldNotCompute()) {} + ScalarEvolutionsImpl(ScalarEvolution &se, Function &f, LoopInfo &li) + : SE(se), F(f), LI(li), UnknownValue(new SCEVCouldNotCompute()) {} /// getSCEV - Return an existing SCEV if it exists, otherwise analyze the /// expression and create a new one. @@ -1289,7 +1301,7 @@ if (SI == Scalars.end()) return; SCEVHandle NV = - SI->second->replaceSymbolicValuesWithConcrete(SymName, NewVal); + SI->second->replaceSymbolicValuesWithConcrete(SymName, NewVal, SE); if (NV == SI->second) return; // No change. SI->second = NV; // Update the scalars map! @@ -1314,7 +1326,7 @@ unsigned BackEdge = IncomingEdge^1; // While we are analyzing this PHI node, handle its value symbolically. - SCEVHandle SymbolicName = SCEVUnknown::get(PN); + SCEVHandle SymbolicName = SE.getUnknown(PN); assert(Scalars.find(PN) == Scalars.end() && "PHI node already processed?"); Scalars.insert(std::make_pair(PN, SymbolicName)); @@ -1345,7 +1357,7 @@ for (unsigned i = 0, e = Add->getNumOperands(); i != e; ++i) if (i != FoundIndex) Ops.push_back(Add->getOperand(i)); - SCEVHandle Accum = SCEVAddExpr::get(Ops); + SCEVHandle Accum = SE.getAddExpr(Ops); // This is not a valid addrec if the step amount is varying each // loop iteration, but is not itself an addrec in this loop. @@ -1353,7 +1365,7 @@ (isa(Accum) && cast(Accum)->getLoop() == L)) { SCEVHandle StartVal = getSCEV(PN->getIncomingValue(IncomingEdge)); - SCEVHandle PHISCEV = SCEVAddRecExpr::get(StartVal, Accum, L); + SCEVHandle PHISCEV = SE.getAddRecExpr(StartVal, Accum, L); // Okay, for the entire analysis of this edge we assumed the PHI // to be symbolic. We now need to go back and update all of the @@ -1375,10 +1387,10 @@ // If StartVal = j.start - j.stride, we can use StartVal as the // initial step of the addrec evolution. - if (StartVal == SCEV::getMinusSCEV(AddRec->getOperand(0), - AddRec->getOperand(1))) { + if (StartVal == SE.getMinusSCEV(AddRec->getOperand(0), + AddRec->getOperand(1))) { SCEVHandle PHISCEV = - SCEVAddRecExpr::get(StartVal, AddRec->getOperand(1), L); + SE.getAddRecExpr(StartVal, AddRec->getOperand(1), L); // Okay, for the entire analysis of this edge we assumed the PHI // to be symbolic. We now need to go back and update all of the @@ -1395,7 +1407,7 @@ } // If it's not a loop phi, we can't handle it yet. - return SCEVUnknown::get(PN); + return SE.getUnknown(PN); } /// GetConstantFactor - Determine the largest constant factor that S has. For @@ -1464,19 +1476,19 @@ if (Instruction *I = dyn_cast(V)) { switch (I->getOpcode()) { case Instruction::Add: - return SCEVAddExpr::get(getSCEV(I->getOperand(0)), - getSCEV(I->getOperand(1))); + return SE.getAddExpr(getSCEV(I->getOperand(0)), + getSCEV(I->getOperand(1))); case Instruction::Mul: - return SCEVMulExpr::get(getSCEV(I->getOperand(0)), - getSCEV(I->getOperand(1))); + return SE.getMulExpr(getSCEV(I->getOperand(0)), + getSCEV(I->getOperand(1))); case Instruction::SDiv: - return SCEVSDivExpr::get(getSCEV(I->getOperand(0)), - getSCEV(I->getOperand(1))); + return SE.getSDivExpr(getSCEV(I->getOperand(0)), + getSCEV(I->getOperand(1))); break; case Instruction::Sub: - return SCEV::getMinusSCEV(getSCEV(I->getOperand(0)), - getSCEV(I->getOperand(1))); + return SE.getMinusSCEV(getSCEV(I->getOperand(0)), + getSCEV(I->getOperand(1))); case Instruction::Or: // If the RHS of the Or is a constant, we may have something like: // X*4+1 which got turned into X*4|1. Handle this as an add so loop @@ -1488,8 +1500,8 @@ "Common factor should at least be 1!"); if (CommonFact.ugt(CI->getValue())) { // If the LHS is a multiple that is larger than the RHS, use +. - return SCEVAddExpr::get(LHS, - getSCEV(I->getOperand(1))); + return SE.getAddExpr(LHS, + getSCEV(I->getOperand(1))); } } break; @@ -1498,8 +1510,8 @@ // Instcombine turns add of signbit into xor as a strength reduction step. if (ConstantInt *CI = dyn_cast(I->getOperand(1))) { if (CI->getValue().isSignBit()) - return SCEVAddExpr::get(getSCEV(I->getOperand(0)), - getSCEV(I->getOperand(1))); + return SE.getAddExpr(getSCEV(I->getOperand(0)), + getSCEV(I->getOperand(1))); } break; @@ -1509,18 +1521,18 @@ uint32_t BitWidth = cast(V->getType())->getBitWidth(); Constant *X = ConstantInt::get( APInt(BitWidth, 1).shl(SA->getLimitedValue(BitWidth))); - return SCEVMulExpr::get(getSCEV(I->getOperand(0)), getSCEV(X)); + return SE.getMulExpr(getSCEV(I->getOperand(0)), getSCEV(X)); } break; case Instruction::Trunc: - return SCEVTruncateExpr::get(getSCEV(I->getOperand(0)), I->getType()); + return SE.getTruncateExpr(getSCEV(I->getOperand(0)), I->getType()); case Instruction::ZExt: - return SCEVZeroExtendExpr::get(getSCEV(I->getOperand(0)), I->getType()); + return SE.getZeroExtendExpr(getSCEV(I->getOperand(0)), I->getType()); case Instruction::SExt: - return SCEVSignExtendExpr::get(getSCEV(I->getOperand(0)), I->getType()); + return SE.getSignExtendExpr(getSCEV(I->getOperand(0)), I->getType()); case Instruction::BitCast: // BitCasts are no-op casts so we just eliminate the cast. @@ -1537,7 +1549,7 @@ } } - return SCEVUnknown::get(V); + return SE.getUnknown(V); } @@ -1673,7 +1685,7 @@ ConstantRange CompRange( ICmpInst::makeConstantRange(Cond, CompVal->getValue())); - SCEVHandle Ret = AddRec->getNumIterationsInRange(CompRange); + SCEVHandle Ret = AddRec->getNumIterationsInRange(CompRange, SE); if (!isa(Ret)) return Ret; } } @@ -1681,13 +1693,13 @@ switch (Cond) { case ICmpInst::ICMP_NE: { // while (X != Y) // Convert to: while (X-Y != 0) - SCEVHandle TC = HowFarToZero(SCEV::getMinusSCEV(LHS, RHS), L); + SCEVHandle TC = HowFarToZero(SE.getMinusSCEV(LHS, RHS), L); if (!isa(TC)) return TC; break; } case ICmpInst::ICMP_EQ: { // Convert to: while (X-Y == 0) // while (X == Y) - SCEVHandle TC = HowFarToNonZero(SCEV::getMinusSCEV(LHS, RHS), L); + SCEVHandle TC = HowFarToNonZero(SE.getMinusSCEV(LHS, RHS), L); if (!isa(TC)) return TC; break; } @@ -1697,8 +1709,8 @@ break; } case ICmpInst::ICMP_SGT: { - SCEVHandle TC = HowManyLessThans(SCEV::getNegativeSCEV(LHS), - SCEV::getNegativeSCEV(RHS), L, true); + SCEVHandle TC = HowManyLessThans(SE.getNegativeSCEV(LHS), + SE.getNegativeSCEV(RHS), L, true); if (!isa(TC)) return TC; break; } @@ -1708,8 +1720,8 @@ break; } case ICmpInst::ICMP_UGT: { - SCEVHandle TC = HowManyLessThans(SCEV::getNegativeSCEV(LHS), - SCEV::getNegativeSCEV(RHS), L, false); + SCEVHandle TC = HowManyLessThans(SE.getNegativeSCEV(LHS), + SE.getNegativeSCEV(RHS), L, false); if (!isa(TC)) return TC; break; } @@ -1729,9 +1741,10 @@ } static ConstantInt * -EvaluateConstantChrecAtConstant(const SCEVAddRecExpr *AddRec, ConstantInt *C) { - SCEVHandle InVal = SCEVConstant::get(C); - SCEVHandle Val = AddRec->evaluateAtIteration(InVal); +EvaluateConstantChrecAtConstant(const SCEVAddRecExpr *AddRec, ConstantInt *C, + ScalarEvolution &SE) { + SCEVHandle InVal = SE.getConstant(C); + SCEVHandle Val = AddRec->evaluateAtIteration(InVal, SE); assert(isa(Val) && "Evaluation of SCEV at constant didn't fold correctly?"); return cast(Val)->getValue(); @@ -1823,7 +1836,7 @@ for (unsigned IterationNum = 0; IterationNum != MaxSteps; ++IterationNum) { ConstantInt *ItCst = ConstantInt::get(IdxExpr->getType(), IterationNum); - ConstantInt *Val = EvaluateConstantChrecAtConstant(IdxExpr, ItCst); + ConstantInt *Val = EvaluateConstantChrecAtConstant(IdxExpr, ItCst, SE); // Form the GEP offset. Indexes[VarIdxNum] = Val; @@ -1841,7 +1854,7 @@ << "***\n"; #endif ++NumArrayLenItCounts; - return SCEVConstant::get(ItCst); // Found terminating iteration! + return SE.getConstant(ItCst); // Found terminating iteration! } } return UnknownValue; @@ -2012,7 +2025,7 @@ if (CondVal->getValue() == uint64_t(ExitWhen)) { ConstantEvolutionLoopExitValue[PN] = PHIVal; ++NumBruteForceTripCountsComputed; - return SCEVConstant::get(ConstantInt::get(Type::Int32Ty, IterationNum)); + return SE.getConstant(ConstantInt::get(Type::Int32Ty, IterationNum)); } // Compute the value of the PHI node for the next iteration. @@ -2053,7 +2066,7 @@ Constant *RV = getConstantEvolutionLoopExitValue(PN, ICC->getValue()->getValue(), LI); - if (RV) return SCEVUnknown::get(RV); + if (RV) return SE.getUnknown(RV); } } @@ -2087,7 +2100,7 @@ } } Constant *C =ConstantFoldInstOperands(I, &Operands[0], Operands.size()); - return SCEVUnknown::get(C); + return SE.getUnknown(C); } } @@ -2113,9 +2126,9 @@ NewOps.push_back(OpAtScope); } if (isa(Comm)) - return SCEVAddExpr::get(NewOps); + return SE.getAddExpr(NewOps); assert(isa(Comm) && "Only know about add and mul!"); - return SCEVMulExpr::get(NewOps); + return SE.getMulExpr(NewOps); } } // If we got here, all operands are loop invariant. @@ -2129,7 +2142,7 @@ if (RHS == UnknownValue) return RHS; if (LHS == Div->getLHS() && RHS == Div->getRHS()) return Div; // must be loop invariant - return SCEVSDivExpr::get(LHS, RHS); + return SE.getSDivExpr(LHS, RHS); } // If this is a loop recurrence for a loop that does not contain L, then we @@ -2141,17 +2154,17 @@ SCEVHandle IterationCount = getIterationCount(AddRec->getLoop()); if (IterationCount == UnknownValue) return UnknownValue; IterationCount = getTruncateOrZeroExtend(IterationCount, - AddRec->getType()); + AddRec->getType(), SE); // If the value is affine, simplify the expression evaluation to just // Start + Step*IterationCount. if (AddRec->isAffine()) - return SCEVAddExpr::get(AddRec->getStart(), - SCEVMulExpr::get(IterationCount, - AddRec->getOperand(1))); + return SE.getAddExpr(AddRec->getStart(), + SE.getMulExpr(IterationCount, + AddRec->getOperand(1))); // Otherwise, evaluate it the hard way. - return AddRec->evaluateAtIteration(IterationCount); + return AddRec->evaluateAtIteration(IterationCount, SE); } return UnknownValue; } @@ -2166,7 +2179,7 @@ /// might be the same) or two SCEVCouldNotCompute objects. /// static std::pair -SolveQuadraticEquation(const SCEVAddRecExpr *AddRec) { +SolveQuadraticEquation(const SCEVAddRecExpr *AddRec, ScalarEvolution &SE) { assert(AddRec->getNumOperands() == 3 && "This is not a quadratic chrec!"); SCEVConstant *LC = dyn_cast(AddRec->getOperand(0)); SCEVConstant *MC = dyn_cast(AddRec->getOperand(1)); @@ -2212,8 +2225,8 @@ ConstantInt *Solution1 = ConstantInt::get((NegB + SqrtVal).sdiv(TwoA)); ConstantInt *Solution2 = ConstantInt::get((NegB - SqrtVal).sdiv(TwoA)); - return std::make_pair(SCEVConstant::get(Solution1), - SCEVConstant::get(Solution2)); + return std::make_pair(SE.getConstant(Solution1), + SE.getConstant(Solution2)); } // end APIntOps namespace } @@ -2248,7 +2261,7 @@ // FIXME: We should add DivExpr and RemExpr operations to our AST. if (SCEVConstant *StepC = dyn_cast(Step)) { if (StepC->getValue()->equalsInt(1)) // N % 1 == 0 - return SCEV::getNegativeSCEV(Start); // 0 - Start/1 == -Start + return SE.getNegativeSCEV(Start); // 0 - Start/1 == -Start if (StepC->getValue()->isAllOnesValue()) // N % -1 == 0 return Start; // 0 - Start/-1 == Start @@ -2259,14 +2272,14 @@ Constant *Rem = ConstantExpr::getSRem(StartNegC, StepC->getValue()); if (Rem->isNullValue()) { Constant *Result =ConstantExpr::getSDiv(StartNegC,StepC->getValue()); - return SCEVUnknown::get(Result); + return SE.getUnknown(Result); } } } } else if (AddRec->isQuadratic() && AddRec->getType()->isInteger()) { // If this is a quadratic (3-term) AddRec {L,+,M,+,N}, find the roots of // the quadratic equation to solve it. - std::pair Roots = SolveQuadraticEquation(AddRec); + std::pair Roots = SolveQuadraticEquation(AddRec, SE); SCEVConstant *R1 = dyn_cast(Roots.first); SCEVConstant *R2 = dyn_cast(Roots.second); if (R1) { @@ -2284,7 +2297,7 @@ // We can only use this value if the chrec ends up with an exact zero // value at this index. When solving for "X*X != 5", for example, we // should not accept a root of 2. - SCEVHandle Val = AddRec->evaluateAtIteration(R1); + SCEVHandle Val = AddRec->evaluateAtIteration(R1, SE); if (SCEVConstant *EvalVal = dyn_cast(Val)) if (EvalVal->getValue()->isZero()) return R1; // We found a quadratic root! @@ -2333,16 +2346,17 @@ if (AddRec->isAffine()) { // FORNOW: We only support unit strides. - SCEVHandle One = SCEVUnknown::getIntegerSCEV(1, RHS->getType()); + SCEVHandle Zero = SE.getIntegerSCEV(0, RHS->getType()); + SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); if (AddRec->getOperand(1) != One) return UnknownValue; - // The number of iterations for "[n,+,1] < m", is m-n. However, we don't + // The number of iterations for "{n,+,1} < m", is m-n. However, we don't // know that m is >= n on input to the loop. If it is, the condition return // true zero times. What we really should return, for full generality, is // SMAX(0, m-n). Since we cannot check this, we will instead check for a // canonical loop form: most do-loops will have a check that dominates the - // loop, that only enters the loop if [n-1]= n. // Search for the check. @@ -2373,6 +2387,7 @@ Value *PreCondLHS = ICI->getOperand(0); Value *PreCondRHS = ICI->getOperand(1); ICmpInst::Predicate Cond; + bool OrEqual = false; if (LoopEntryPredicate->getSuccessor(0) == PreheaderDest) Cond = ICI->getPredicate(); else @@ -2395,23 +2410,60 @@ case ICmpInst::ICMP_SLT: if (!isSigned) return UnknownValue; break; + case ICmpInst::ICMP_UGE: + if (isSigned) return UnknownValue; + std::swap(PreCondLHS, PreCondRHS); + Cond = ICmpInst::ICMP_ULE; + OrEqual = true; + break; + case ICmpInst::ICMP_SGE: + if (!isSigned) return UnknownValue; + std::swap(PreCondLHS, PreCondRHS); + Cond = ICmpInst::ICMP_SLE; + OrEqual = true; + break; + case ICmpInst::ICMP_ULE: + if (isSigned) return UnknownValue; + OrEqual = true; + break; + case ICmpInst::ICMP_SLE: + if (!isSigned) return UnknownValue; + OrEqual = true; + break; default: return UnknownValue; } if (PreCondLHS->getType()->isInteger()) { - if (RHS != getSCEV(PreCondRHS)) - return UnknownValue; // Not a comparison against 'm'. - - if (SCEV::getMinusSCEV(AddRec->getOperand(0), One) - != getSCEV(PreCondLHS)) - return UnknownValue; // Not a comparison against 'n-1'. + SCEVHandle PreCondRHSSCEV = getSCEV(PreCondRHS); + SCEVHandle PreCondLHSSCEV = getSCEV(PreCondLHS); + SCEVHandle LHSStart = AddRec->getStart(); + if (OrEqual) { + if (LHSStart == PreCondLHSSCEV && + RHS == PreCondRHSSCEV) { + // n <= m + } else if (SE.getMinusSCEV(LHSStart, RHS) == PreCondLHSSCEV && + Zero == PreCondRHSSCEV) { + // (n-m) <= 0 + } else return UnknownValue; + } else { + if (SE.getMinusSCEV(LHSStart, One) == PreCondLHSSCEV && + RHS == PreCondRHSSCEV) { + // (n-1) < m + } else if (SE.getMinusSCEV(LHSStart, RHS) == PreCondLHSSCEV && + One == PreCondRHSSCEV) { + // (n-m) < 1 + } else if (SE.getMinusSCEV(SE.getMinusSCEV(LHSStart, RHS), One) == PreCondLHSSCEV && + Zero == PreCondLHSSCEV) { + // (n-m-1) < 0 + } else return UnknownValue; + } } else return UnknownValue; // cerr << "Computed Loop Trip Count as: " - // << // *SCEV::getMinusSCEV(RHS, AddRec->getOperand(0)) << "\n"; - return SCEV::getMinusSCEV(RHS, AddRec->getOperand(0)); + // << // *SE.getMinusSCEV(RHS, AddRec->getOperand(0)) << "\n"; + return SE.getMinusSCEV(RHS, AddRec->getOperand(0)); } else return UnknownValue; @@ -2425,7 +2477,8 @@ /// this is that it returns the first iteration number where the value is not in /// the condition, thus computing the exit count. If the iteration count can't /// be computed, an instance of SCEVCouldNotCompute is returned. -SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range) const { +SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range, + ScalarEvolution &SE) const { if (Range.isFullSet()) // Infinite loop. return new SCEVCouldNotCompute(); @@ -2433,11 +2486,11 @@ if (SCEVConstant *SC = dyn_cast(getStart())) if (!SC->getValue()->isZero()) { std::vector Operands(op_begin(), op_end()); - Operands[0] = SCEVUnknown::getIntegerSCEV(0, SC->getType()); - SCEVHandle Shifted = SCEVAddRecExpr::get(Operands, getLoop()); + Operands[0] = SE.getIntegerSCEV(0, SC->getType()); + SCEVHandle Shifted = SE.getAddRecExpr(Operands, getLoop()); if (SCEVAddRecExpr *ShiftedAddRec = dyn_cast(Shifted)) return ShiftedAddRec->getNumIterationsInRange( - Range.subtract(SC->getValue()->getValue())); + Range.subtract(SC->getValue()->getValue()), SE); // This is strange and shouldn't happen. return new SCEVCouldNotCompute(); } @@ -2455,7 +2508,7 @@ // First check to see if the range contains zero. If not, the first // iteration exits. if (!Range.contains(APInt(getBitWidth(),0))) - return SCEVConstant::get(ConstantInt::get(getType(),0)); + return SE.getConstant(ConstantInt::get(getType(),0)); if (isAffine()) { // If this is an affine expression then we have this situation: @@ -2476,28 +2529,28 @@ // Evaluate at the exit value. If we really did fall out of the valid // range, then we computed our trip count, otherwise wrap around or other // things must have happened. - ConstantInt *Val = EvaluateConstantChrecAtConstant(this, ExitValue); + ConstantInt *Val = EvaluateConstantChrecAtConstant(this, ExitValue, SE); if (Range.contains(Val->getValue())) return new SCEVCouldNotCompute(); // Something strange happened // Ensure that the previous value is in the range. This is a sanity check. assert(Range.contains( EvaluateConstantChrecAtConstant(this, - ConstantInt::get(ExitVal - One))->getValue()) && + ConstantInt::get(ExitVal - One), SE)->getValue()) && "Linear scev computation is off in a bad way!"); - return SCEVConstant::get(ExitValue); + return SE.getConstant(ExitValue); } else if (isQuadratic()) { // If this is a quadratic (3-term) AddRec {L,+,M,+,N}, find the roots of the // quadratic equation to solve it. To do this, we must frame our problem in // terms of figuring out when zero is crossed, instead of when // Range.getUpper() is crossed. std::vector NewOps(op_begin(), op_end()); - NewOps[0] = SCEV::getNegativeSCEV(SCEVConstant::get(Range.getUpper())); - SCEVHandle NewAddRec = SCEVAddRecExpr::get(NewOps, getLoop()); + NewOps[0] = SE.getNegativeSCEV(SE.getConstant(Range.getUpper())); + SCEVHandle NewAddRec = SE.getAddRecExpr(NewOps, getLoop()); // Next, solve the constructed addrec std::pair Roots = - SolveQuadraticEquation(cast(NewAddRec)); + SolveQuadraticEquation(cast(NewAddRec), SE); SCEVConstant *R1 = dyn_cast(Roots.first); SCEVConstant *R2 = dyn_cast(Roots.second); if (R1) { @@ -2512,21 +2565,22 @@ // not be in the range, but the previous one should be. When solving // for "X*X < 5", for example, we should not return a root of 2. ConstantInt *R1Val = EvaluateConstantChrecAtConstant(this, - R1->getValue()); + R1->getValue(), + SE); if (Range.contains(R1Val->getValue())) { // The next iteration must be out of the range... ConstantInt *NextVal = ConstantInt::get(R1->getValue()->getValue()+1); - R1Val = EvaluateConstantChrecAtConstant(this, NextVal); + R1Val = EvaluateConstantChrecAtConstant(this, NextVal, SE); if (!Range.contains(R1Val->getValue())) - return SCEVConstant::get(NextVal); + return SE.getConstant(NextVal); return new SCEVCouldNotCompute(); // Something strange happened } // If R1 was not in the range, then it is a good return value. Make // sure that R1-1 WAS in the range though, just in case. ConstantInt *NextVal = ConstantInt::get(R1->getValue()->getValue()-1); - R1Val = EvaluateConstantChrecAtConstant(this, NextVal); + R1Val = EvaluateConstantChrecAtConstant(this, NextVal, SE); if (Range.contains(R1Val->getValue())) return R1; return new SCEVCouldNotCompute(); // Something strange happened @@ -2543,13 +2597,13 @@ ConstantInt *EndVal = TestVal; // Stop when we wrap around. do { ++NumBruteForceEvaluations; - SCEVHandle Val = evaluateAtIteration(SCEVConstant::get(TestVal)); + SCEVHandle Val = evaluateAtIteration(SE.getConstant(TestVal), SE); if (!isa(Val)) // This shouldn't happen. return new SCEVCouldNotCompute(); // Check to see if we found the value! if (!Range.contains(cast(Val)->getValue()->getValue())) - return SCEVConstant::get(TestVal); + return SE.getConstant(TestVal); // Increment to test the next index. TestVal = ConstantInt::get(TestVal->getValue()+1); @@ -2565,7 +2619,7 @@ //===----------------------------------------------------------------------===// bool ScalarEvolution::runOnFunction(Function &F) { - Impl = new ScalarEvolutionsImpl(F, getAnalysis()); + Impl = new ScalarEvolutionsImpl(*this, F, getAnalysis()); return false; } Index: lib/Transforms/Scalar/IndVarSimplify.cpp =================================================================== --- lib/Transforms/Scalar/IndVarSimplify.cpp (revision 42847) +++ lib/Transforms/Scalar/IndVarSimplify.cpp (working copy) @@ -268,7 +268,7 @@ // backedge actually branches to the loop header. This is one less than the // number of times the loop executes, so add one to it. ConstantInt *OneC = ConstantInt::get(IterationCount->getType(), 1); - TripCount = SCEVAddExpr::get(IterationCount, SCEVConstant::get(OneC)); + TripCount = SE->getAddExpr(IterationCount, SE->getConstant(OneC)); IndVar = L->getCanonicalInductionVariableIncrement(); } else { // We have to use the preincremented value... @@ -524,9 +524,9 @@ if (!isa(IterationCount)) { if (IterationCount->getType()->getPrimitiveSizeInBits() < LargestType->getPrimitiveSizeInBits()) - IterationCount = SCEVZeroExtendExpr::get(IterationCount, LargestType); + IterationCount = SE->getZeroExtendExpr(IterationCount, LargestType); else if (IterationCount->getType() != LargestType) - IterationCount = SCEVTruncateExpr::get(IterationCount, LargestType); + IterationCount = SE->getTruncateExpr(IterationCount, LargestType); if (Instruction *DI = LinearFunctionTestReplace(L, IterationCount,Rewriter)) DeadInsts.insert(DI); } Index: lib/Transforms/Scalar/LoopStrengthReduce.cpp =================================================================== --- lib/Transforms/Scalar/LoopStrengthReduce.cpp (revision 42847) +++ lib/Transforms/Scalar/LoopStrengthReduce.cpp (working copy) @@ -90,9 +90,6 @@ PHINode *PHI; Value *IncV; - IVExpr() - : Stride(SCEVUnknown::getIntegerSCEV(0, Type::Int32Ty)), - Base (SCEVUnknown::getIntegerSCEV(0, Type::Int32Ty)) {} IVExpr(const SCEVHandle &stride, const SCEVHandle &base, PHINode *phi, Value *incv) : Stride(stride), Base(base), PHI(phi), IncV(incv) {} @@ -261,7 +258,7 @@ // Build up the base expression. Insert an LLVM cast of the pointer to // uintptr_t first. - SCEVHandle GEPVal = SCEVUnknown::get( + SCEVHandle GEPVal = SE->getUnknown( getCastedVersionOf(Instruction::PtrToInt, GEP->getOperand(0))); gep_type_iterator GTI = gep_type_begin(GEP); @@ -274,8 +271,8 @@ const StructLayout *SL = TD->getStructLayout(STy); unsigned Idx = cast(GEP->getOperand(i))->getZExtValue(); uint64_t Offset = SL->getElementOffset(Idx); - GEPVal = SCEVAddExpr::get(GEPVal, - SCEVUnknown::getIntegerSCEV(Offset, UIntPtrTy)); + GEPVal = SE->getAddExpr(GEPVal, + SE->getIntegerSCEV(Offset, UIntPtrTy)); } else { unsigned GEPOpiBits = GEP->getOperand(i)->getType()->getPrimitiveSizeInBits(); @@ -288,10 +285,10 @@ uint64_t TypeSize = TD->getABITypeSize(GTI.getIndexedType()); if (TypeSize != 1) - Idx = SCEVMulExpr::get(Idx, - SCEVConstant::get(ConstantInt::get(UIntPtrTy, - TypeSize))); - GEPVal = SCEVAddExpr::get(GEPVal, Idx); + Idx = SE->getMulExpr(Idx, + SE->getConstant(ConstantInt::get(UIntPtrTy, + TypeSize))); + GEPVal = SE->getAddExpr(GEPVal, Idx); } } @@ -304,7 +301,8 @@ /// is. The stride must be a loop invariant expression, but the start may be /// a mix of loop invariant and loop variant expressions. static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, - SCEVHandle &Start, SCEVHandle &Stride) { + SCEVHandle &Start, SCEVHandle &Stride, + ScalarEvolution *SE) { SCEVHandle TheAddRec = Start; // Initialize to zero. // If the outer level is an AddExpr, the operands are all start values except @@ -314,11 +312,11 @@ if (SCEVAddRecExpr *AddRec = dyn_cast(AE->getOperand(i))) { if (AddRec->getLoop() == L) - TheAddRec = SCEVAddExpr::get(AddRec, TheAddRec); + TheAddRec = SE->getAddExpr(AddRec, TheAddRec); else return false; // Nested IV of some sort? } else { - Start = SCEVAddExpr::get(Start, AE->getOperand(i)); + Start = SE->getAddExpr(Start, AE->getOperand(i)); } } else if (isa(SH)) { @@ -333,7 +331,7 @@ // FIXME: Generalize to non-affine IV's. if (!AddRec->isAffine()) return false; - Start = SCEVAddExpr::get(Start, AddRec->getOperand(0)); + Start = SE->getAddExpr(Start, AddRec->getOperand(0)); if (!isa(AddRec->getOperand(1))) DOUT << "[" << L->getHeader()->getName() @@ -414,9 +412,9 @@ if (isa(ISE)) return false; // Get the start and stride for this expression. - SCEVHandle Start = SCEVUnknown::getIntegerSCEV(0, ISE->getType()); + SCEVHandle Start = SE->getIntegerSCEV(0, ISE->getType()); SCEVHandle Stride = Start; - if (!getSCEVStartAndStride(ISE, L, Start, Stride)) + if (!getSCEVStartAndStride(ISE, L, Start, Stride, SE)) return false; // Non-reducible symbolic expression, bail out. std::vector IUsers; @@ -458,7 +456,7 @@ if (IVUseShouldUsePostIncValue(User, I, L, DT, this)) { // The value used will be incremented by the stride more than we are // expecting, so subtract this off. - SCEVHandle NewStart = SCEV::getMinusSCEV(Start, Stride); + SCEVHandle NewStart = SE->getMinusSCEV(Start, Stride); StrideUses.addUser(NewStart, User, I); StrideUses.Users.back().isUseOfPostIncrementedValue = true; DOUT << " USING POSTINC SCEV, START=" << *NewStart<< "\n"; @@ -474,6 +472,9 @@ /// BasedUser - For a particular base value, keep information about how we've /// partitioned the expression so far. struct BasedUser { + /// SE - The current ScalarEvolution object. + ScalarEvolution *SE; + /// Base - The Base value for the PHI node that needs to be inserted for /// this use. As the use is processed, information gets moved from this /// field to the Imm field (below). BasedUser values are sorted by this @@ -503,10 +504,10 @@ // the loop. bool isUseOfPostIncrementedValue; - BasedUser(IVStrideUse &IVSU) - : Base(IVSU.Offset), Inst(IVSU.User), + BasedUser(IVStrideUse &IVSU, ScalarEvolution *se) + : SE(se), Base(IVSU.Offset), Inst(IVSU.User), OperandValToReplace(IVSU.OperandValToReplace), - Imm(SCEVUnknown::getIntegerSCEV(0, Base->getType())), EmittedBase(0), + Imm(SE->getIntegerSCEV(0, Base->getType())), EmittedBase(0), isUseOfPostIncrementedValue(IVSU.isUseOfPostIncrementedValue) {} // Once we rewrite the code to insert the new IVs we want, update the @@ -565,7 +566,7 @@ IP = Rewriter.getInsertionPoint(); // Always emit the immediate (if non-zero) into the same block as the user. - SCEVHandle NewValSCEV = SCEVAddExpr::get(SCEVUnknown::get(Base), Imm); + SCEVHandle NewValSCEV = SE->getAddExpr(SE->getUnknown(Base), Imm); return Rewriter.expandCodeFor(NewValSCEV, IP); } @@ -703,7 +704,7 @@ /// MoveLoopVariantsToImediateField - Move any subexpressions from Val that are /// loop varying to the Imm operand. static void MoveLoopVariantsToImediateField(SCEVHandle &Val, SCEVHandle &Imm, - Loop *L) { + Loop *L, ScalarEvolution *SE) { if (Val->isLoopInvariant(L)) return; // Nothing to do. if (SCEVAddExpr *SAE = dyn_cast(Val)) { @@ -714,27 +715,27 @@ if (!SAE->getOperand(i)->isLoopInvariant(L)) { // If this is a loop-variant expression, it must stay in the immediate // field of the expression. - Imm = SCEVAddExpr::get(Imm, SAE->getOperand(i)); + Imm = SE->getAddExpr(Imm, SAE->getOperand(i)); } else { NewOps.push_back(SAE->getOperand(i)); } if (NewOps.empty()) - Val = SCEVUnknown::getIntegerSCEV(0, Val->getType()); + Val = SE->getIntegerSCEV(0, Val->getType()); else - Val = SCEVAddExpr::get(NewOps); + Val = SE->getAddExpr(NewOps); } else if (SCEVAddRecExpr *SARE = dyn_cast(Val)) { // Try to pull immediates out of the start value of nested addrec's. SCEVHandle Start = SARE->getStart(); - MoveLoopVariantsToImediateField(Start, Imm, L); + MoveLoopVariantsToImediateField(Start, Imm, L, SE); std::vector Ops(SARE->op_begin(), SARE->op_end()); Ops[0] = Start; - Val = SCEVAddRecExpr::get(Ops, SARE->getLoop()); + Val = SE->getAddRecExpr(Ops, SARE->getLoop()); } else { // Otherwise, all of Val is variant, move the whole thing over. - Imm = SCEVAddExpr::get(Imm, Val); - Val = SCEVUnknown::getIntegerSCEV(0, Val->getType()); + Imm = SE->getAddExpr(Imm, Val); + Val = SE->getIntegerSCEV(0, Val->getType()); } } @@ -745,7 +746,8 @@ static void MoveImmediateValues(const TargetLowering *TLI, Instruction *User, SCEVHandle &Val, SCEVHandle &Imm, - bool isAddress, Loop *L) { + bool isAddress, Loop *L, + ScalarEvolution *SE) { const Type *UseTy = User->getType(); if (StoreInst *SI = dyn_cast(User)) UseTy = SI->getOperand(0)->getType(); @@ -756,31 +758,31 @@ for (unsigned i = 0; i != SAE->getNumOperands(); ++i) { SCEVHandle NewOp = SAE->getOperand(i); - MoveImmediateValues(TLI, User, NewOp, Imm, isAddress, L); + MoveImmediateValues(TLI, User, NewOp, Imm, isAddress, L, SE); if (!NewOp->isLoopInvariant(L)) { // If this is a loop-variant expression, it must stay in the immediate // field of the expression. - Imm = SCEVAddExpr::get(Imm, NewOp); + Imm = SE->getAddExpr(Imm, NewOp); } else { NewOps.push_back(NewOp); } } if (NewOps.empty()) - Val = SCEVUnknown::getIntegerSCEV(0, Val->getType()); + Val = SE->getIntegerSCEV(0, Val->getType()); else - Val = SCEVAddExpr::get(NewOps); + Val = SE->getAddExpr(NewOps); return; } else if (SCEVAddRecExpr *SARE = dyn_cast(Val)) { // Try to pull immediates out of the start value of nested addrec's. SCEVHandle Start = SARE->getStart(); - MoveImmediateValues(TLI, User, Start, Imm, isAddress, L); + MoveImmediateValues(TLI, User, Start, Imm, isAddress, L, SE); if (Start != SARE->getStart()) { std::vector Ops(SARE->op_begin(), SARE->op_end()); Ops[0] = Start; - Val = SCEVAddRecExpr::get(Ops, SARE->getLoop()); + Val = SE->getAddRecExpr(Ops, SARE->getLoop()); } return; } else if (SCEVMulExpr *SME = dyn_cast(Val)) { @@ -788,22 +790,22 @@ if (isAddress && isTargetConstant(SME->getOperand(0), UseTy, TLI) && SME->getNumOperands() == 2 && SME->isLoopInvariant(L)) { - SCEVHandle SubImm = SCEVUnknown::getIntegerSCEV(0, Val->getType()); + SCEVHandle SubImm = SE->getIntegerSCEV(0, Val->getType()); SCEVHandle NewOp = SME->getOperand(1); - MoveImmediateValues(TLI, User, NewOp, SubImm, isAddress, L); + MoveImmediateValues(TLI, User, NewOp, SubImm, isAddress, L, SE); // If we extracted something out of the subexpressions, see if we can // simplify this! if (NewOp != SME->getOperand(1)) { // Scale SubImm up by "8". If the result is a target constant, we are // good. - SubImm = SCEVMulExpr::get(SubImm, SME->getOperand(0)); + SubImm = SE->getMulExpr(SubImm, SME->getOperand(0)); if (isTargetConstant(SubImm, UseTy, TLI)) { // Accumulate the immediate. - Imm = SCEVAddExpr::get(Imm, SubImm); + Imm = SE->getAddExpr(Imm, SubImm); // Update what is left of 'Val'. - Val = SCEVMulExpr::get(SME->getOperand(0), NewOp); + Val = SE->getMulExpr(SME->getOperand(0), NewOp); return; } } @@ -814,8 +816,8 @@ // expression. if ((isAddress && isTargetConstant(Val, UseTy, TLI)) || !Val->isLoopInvariant(L)) { - Imm = SCEVAddExpr::get(Imm, Val); - Val = SCEVUnknown::getIntegerSCEV(0, Val->getType()); + Imm = SE->getAddExpr(Imm, Val); + Val = SE->getIntegerSCEV(0, Val->getType()); return; } @@ -827,22 +829,23 @@ /// added together. This is used to reassociate common addition subexprs /// together for maximal sharing when rewriting bases. static void SeparateSubExprs(std::vector &SubExprs, - SCEVHandle Expr) { + SCEVHandle Expr, + ScalarEvolution *SE) { if (SCEVAddExpr *AE = dyn_cast(Expr)) { for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j) - SeparateSubExprs(SubExprs, AE->getOperand(j)); + SeparateSubExprs(SubExprs, AE->getOperand(j), SE); } else if (SCEVAddRecExpr *SARE = dyn_cast(Expr)) { - SCEVHandle Zero = SCEVUnknown::getIntegerSCEV(0, Expr->getType()); + SCEVHandle Zero = SE->getIntegerSCEV(0, Expr->getType()); if (SARE->getOperand(0) == Zero) { SubExprs.push_back(Expr); } else { // Compute the addrec with zero as its base. std::vector Ops(SARE->op_begin(), SARE->op_end()); Ops[0] = Zero; // Start with zero base. - SubExprs.push_back(SCEVAddRecExpr::get(Ops, SARE->getLoop())); + SubExprs.push_back(SE->getAddRecExpr(Ops, SARE->getLoop())); - SeparateSubExprs(SubExprs, SARE->getOperand(0)); + SeparateSubExprs(SubExprs, SARE->getOperand(0), SE); } } else if (!isa(Expr) || !cast(Expr)->getValue()->isZero()) { @@ -857,11 +860,12 @@ /// removed, accumulated, and returned. This looks for things like (a+b+c) and /// (a+c+d) -> (a+c). The common expression is *removed* from the Bases. static SCEVHandle -RemoveCommonExpressionsFromUseBases(std::vector &Uses) { +RemoveCommonExpressionsFromUseBases(std::vector &Uses, + ScalarEvolution *SE) { unsigned NumUses = Uses.size(); // Only one use? Use its base, regardless of what it is! - SCEVHandle Zero = SCEVUnknown::getIntegerSCEV(0, Uses[0].Base->getType()); + SCEVHandle Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType()); SCEVHandle Result = Zero; if (NumUses == 1) { std::swap(Result, Uses[0].Base); @@ -883,7 +887,7 @@ if (Uses[i].Base == Zero) return Zero; // Split the expression into subexprs. - SeparateSubExprs(SubExprs, Uses[i].Base); + SeparateSubExprs(SubExprs, Uses[i].Base, SE); // Add one to SubExpressionUseCounts for each subexpr present. for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) if (++SubExpressionUseCounts[SubExprs[j]] == 1) @@ -898,7 +902,7 @@ SubExpressionUseCounts.find(UniqueSubExprs[i]); assert(I != SubExpressionUseCounts.end() && "Entry not found?"); if (I->second == NumUses) { // Found CSE! - Result = SCEVAddExpr::get(Result, I->first); + Result = SE->getAddExpr(Result, I->first); } else { // Remove non-cse's from SubExpressionUseCounts. SubExpressionUseCounts.erase(I); @@ -911,7 +915,7 @@ // Otherwise, remove all of the CSE's we found from each of the base values. for (unsigned i = 0; i != NumUses; ++i) { // Split the expression into subexprs. - SeparateSubExprs(SubExprs, Uses[i].Base); + SeparateSubExprs(SubExprs, Uses[i].Base, SE); // Remove any common subexpressions. for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) @@ -924,7 +928,7 @@ if (SubExprs.empty()) Uses[i].Base = Zero; else - Uses[i].Base = SCEVAddExpr::get(SubExprs); + Uses[i].Base = SE->getAddExpr(SubExprs); SubExprs.clear(); } @@ -1037,13 +1041,13 @@ std::vector UsersToProcess; UsersToProcess.reserve(Uses.Users.size()); for (unsigned i = 0, e = Uses.Users.size(); i != e; ++i) { - UsersToProcess.push_back(Uses.Users[i]); + UsersToProcess.push_back(BasedUser(Uses.Users[i], SE)); // Move any loop invariant operands from the offset field to the immediate // field of the use, so that we don't try to use something before it is // computed. MoveLoopVariantsToImediateField(UsersToProcess.back().Base, - UsersToProcess.back().Imm, L); + UsersToProcess.back().Imm, L, SE); assert(UsersToProcess.back().Base->isLoopInvariant(L) && "Base value is not loop invariant!"); } @@ -1056,7 +1060,7 @@ // "A+B"), emit it to the preheader, then remove the expression from the // UsersToProcess base values. SCEVHandle CommonExprs = - RemoveCommonExpressionsFromUseBases(UsersToProcess); + RemoveCommonExpressionsFromUseBases(UsersToProcess, SE); // Next, figure out what we can represent in the immediate fields of // instructions. If we can represent anything there, move it to the imm @@ -1067,10 +1071,10 @@ // value of the IV. Do not put anything in the base, make sure it's all in // the immediate field to allow as much factoring as possible. if (!L->contains(UsersToProcess[i].Inst->getParent())) { - UsersToProcess[i].Imm = SCEVAddExpr::get(UsersToProcess[i].Imm, - UsersToProcess[i].Base); + UsersToProcess[i].Imm = SE->getAddExpr(UsersToProcess[i].Imm, + UsersToProcess[i].Base); UsersToProcess[i].Base = - SCEVUnknown::getIntegerSCEV(0, UsersToProcess[i].Base->getType()); + SE->getIntegerSCEV(0, UsersToProcess[i].Base->getType()); } else { // Addressing modes can be folded into loads and stores. Be careful that @@ -1088,7 +1092,7 @@ } MoveImmediateValues(TLI, UsersToProcess[i].Inst, UsersToProcess[i].Base, - UsersToProcess[i].Imm, isAddress, L); + UsersToProcess[i].Imm, isAddress, L, SE); } } @@ -1098,7 +1102,9 @@ // instruction after this substition, including the immediate field, if any. PHINode *NewPHI = NULL; Value *IncV = NULL; - IVExpr ReuseIV; + IVExpr ReuseIV(SE->getIntegerSCEV(0, Type::Int32Ty), + SE->getIntegerSCEV(0, Type::Int32Ty), + 0, 0); unsigned RewriteFactor = CheckForIVReuse(Stride, ReuseIV, CommonExprs->getType(), UsersToProcess); @@ -1143,7 +1149,7 @@ bool isNegative = isNonConstantNegative(Stride); SCEVHandle IncAmount = Stride; if (isNegative) - IncAmount = SCEV::getNegativeSCEV(Stride); + IncAmount = SE->getNegativeSCEV(Stride); // Insert the stride into the preheader. Value *StrideV = PreheaderRewriter.expandCodeFor(IncAmount, PreInsertPt); @@ -1151,10 +1157,10 @@ // Emit the increment of the base value before the terminator of the loop // latch block, and add it to the Phi node. - SCEVHandle IncExp = SCEVUnknown::get(StrideV); + SCEVHandle IncExp = SE->getUnknown(StrideV); if (isNegative) - IncExp = SCEV::getNegativeSCEV(IncExp); - IncExp = SCEVAddExpr::get(SCEVUnknown::get(NewPHI), IncExp); + IncExp = SE->getNegativeSCEV(IncExp); + IncExp = SE->getAddExpr(SE->getUnknown(NewPHI), IncExp); IncV = Rewriter.expandCodeFor(IncExp, LatchBlock->getTerminator()); IncV->setName(NewPHI->getName()+".inc"); @@ -1168,7 +1174,7 @@ Constant *C = dyn_cast(CommonBaseV); if (!C || (!C->isNullValue() && - !isTargetConstant(SCEVUnknown::get(CommonBaseV), ReplacedTy, TLI))) + !isTargetConstant(SE->getUnknown(CommonBaseV), ReplacedTy, TLI))) // We want the common base emitted into the preheader! This is just // using cast as a copy so BitCast (no-op cast) is appropriate CommonBaseV = new BitCastInst(CommonBaseV, CommonBaseV->getType(), @@ -1257,7 +1263,7 @@ RewriteOp = SCEVExpander::InsertCastOfTo(opcode, RewriteOp, ReplacedTy); } - SCEVHandle RewriteExpr = SCEVUnknown::get(RewriteOp); + SCEVHandle RewriteExpr = SE->getUnknown(RewriteOp); // Clear the SCEVExpander's expression map so that we are guaranteed // to have the code emitted where we expect it. @@ -1267,8 +1273,8 @@ // factor take advantage of addressing mode scale component. if (RewriteFactor != 0) { RewriteExpr = - SCEVMulExpr::get(SCEVUnknown::getIntegerSCEV(RewriteFactor, - RewriteExpr->getType()), + SE->getMulExpr(SE->getIntegerSCEV(RewriteFactor, + RewriteExpr->getType()), RewriteExpr); // The common base is emitted in the loop preheader. But since we @@ -1276,15 +1282,15 @@ // Add it to the expression used to rewrite the uses. if (!isa(CommonBaseV) || !cast(CommonBaseV)->isZero()) - RewriteExpr = SCEVAddExpr::get(RewriteExpr, - SCEVUnknown::get(CommonBaseV)); + RewriteExpr = SE->getAddExpr(RewriteExpr, + SE->getUnknown(CommonBaseV)); } // Now that we know what we need to do, insert code before User for the // immediate and any loop-variant expressions. if (!isa(BaseV) || !cast(BaseV)->isZero()) // Add BaseV to the PHI value if needed. - RewriteExpr = SCEVAddExpr::get(RewriteExpr, SCEVUnknown::get(BaseV)); + RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(BaseV)); User.RewriteInstructionToUseNewBase(RewriteExpr, Rewriter, L, this); @@ -1380,7 +1386,7 @@ // If we get to here, we know that we can transform the setcc instruction to // use the post-incremented version of the IV, allowing us to coalesce the // live ranges for the IV correctly. - CondUse->Offset = SCEV::getMinusSCEV(CondUse->Offset, *CondStride); + CondUse->Offset = SE->getMinusSCEV(CondUse->Offset, *CondStride); CondUse->isUseOfPostIncrementedValue = true; } From kremenek at apple.com Thu Oct 11 16:51:04 2007 From: kremenek at apple.com (Ted Kremenek) Date: Thu, 11 Oct 2007 21:51:04 -0000 Subject: [llvm-commits] [llvm] r42877 - /llvm/trunk/include/llvm/ADT/ImmutableSet.h Message-ID: <200710112151.l9BLp4ZY004933@zion.cs.uiuc.edu> Author: kremenek Date: Thu Oct 11 16:51:04 2007 New Revision: 42877 URL: http://llvm.org/viewvc/llvm-project?rev=42877&view=rev Log: Provided accessors to internal allocator for ImutAVLTree and ImmutableSet. Added postfix ++,-- support for ImmutableSet::iterator. Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=42877&r1=42876&r2=42877&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original) +++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Thu Oct 11 16:51:04 2007 @@ -294,6 +294,8 @@ TreeTy* GetEmptyTree() const { return NULL; } + BumpPtrAllocator& getAllocator() { return Allocator; } + //===--------------------------------------------------===// // A bunch of quick helper functions used for reasoning // about the properties of trees and their children. @@ -336,6 +338,7 @@ // FIXME: more intelligent calculation of alignment. TreeTy* T = (TreeTy*) Allocator.Allocate(sizeof(*T),16); + new (T) TreeTy(L,R,V,IncrementHeight(L,R)); Cache.InsertNode(T,InsertPos); @@ -816,6 +819,8 @@ return ImmutableSet(F.Remove(Old.Root,V)); } + BumpPtrAllocator& getAllocator() { return F.getAllocator(); } + private: Factory(const Factory& RHS) {}; void operator=(const Factory& RHS) {}; @@ -858,7 +863,9 @@ public: inline value_type_ref operator*() const { return itr->getValue(); } inline iterator& operator++() { ++itr; return *this; } + inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; } inline iterator& operator--() { --itr; return *this; } + inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; } inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; } inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; } }; From djg at cray.com Thu Oct 11 17:08:55 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 11 Oct 2007 17:08:55 -0500 Subject: [llvm-commits] [llvm] r42864 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll Message-ID: <20071011220855.GB21991@village.us.cray.com> > + // If MemCpyInst length is 1/2/4/8 bytes then replace memcpy with load/store Neat! > + ConstantInt *MemOpLength = dyn_cast(CI.getOperand(3)); > + if (isa(MI)) > + if (MemOpLength) { Can you replace these two if statements with if (isa(MI) && MemOpLength) { ? Then the indentation of what follows won't be wrong either :-) > + unsigned Size = MemOpLength->getZExtValue(); > + unsigned Align = cast(CI.getOperand(4))->getZExtValue(); > + const PointerType *PTy = cast(CI.getOperand(1)->getType()); > + const Type *MTy = PTy->getElementType(); > + PointerType *NewPtrTy = NULL; > + if (MTy == Type::Int8Ty) { > + if (Size == 8) > + NewPtrTy = PointerType::get(Type::Int64Ty); > + else if (Size == 4) > + NewPtrTy = PointerType::get(Type::Int32Ty); > + else if (Size == 2) > + NewPtrTy = PointerType::get(Type::Int16Ty); > + else if (Size == 1) > + NewPtrTy = PointerType::get(Type::Int8Ty); > + } else if (MTy == Type::Int16Ty) { > + if (Size == 4) > + NewPtrTy = PointerType::get(Type::Int64Ty); > + else if (Size == 2) > + NewPtrTy = PointerType::get(Type::Int32Ty); > + else if (Size == 1) > + NewPtrTy = PointerType::get(Type::Int16Ty); > + } else if (MTy == Type::Int32Ty) { > + if (Size == 2) > + NewPtrTy = PointerType::get(Type::Int64Ty); > + else if (Size == 1) > + NewPtrTy = PointerType::get(Type::Int32Ty); > + } else if (MTy == Type::Int64Ty) { > + if (Size == 1) > + NewPtrTy = PointerType::get(Type::Int64Ty); > + } It'd be great it this worked for non-scalar-integer types as well. Maybe you could do something like (warning, untested): if (Size == 1 && MTy->isFirstClassType()) NewPtrTy = PointerType::get(MTy) else { CopySize = Size * TD->getABITypeSizeInBits(MTy); if (CopySize == 8 || CopySize == 4 || CopySize == 2 || CopySize == 1) NewPtrTy = PointerType::get(IntegerType::get(CopySize)); } ? > + if (NewPtrTy) > + { LLVM style. > + Value *Src = InsertCastBefore(Instruction::BitCast, CI.getOperand(2), NewPtrTy, CI); > + Value *Dest = InsertCastBefore(Instruction::BitCast, CI.getOperand(1), NewPtrTy, CI); This is more than 80 columns. > + Value *L = new LoadInst(Src, "tmp", false, Align, &CI); > + Value *NS = new StoreInst(L, Dest, false, Align, &CI); > + CI.replaceAllUsesWith(NS); > + Changed = true; > + return EraseInstFromFunction(CI); > + } > + } From djg at cray.com Thu Oct 11 17:26:30 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 11 Oct 2007 17:26:30 -0500 Subject: [llvm-commits] [llvm] r42864 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll In-Reply-To: <20071011220855.GB21991@village.us.cray.com> References: <20071011220855.GB21991@village.us.cray.com> Message-ID: <20071011222630.GC21991@village.us.cray.com> On Thu, Oct 11, 2007 at 05:08:55PM -0500, Dan Gohman wrote: > > + unsigned Size = MemOpLength->getZExtValue(); > > + unsigned Align = cast(CI.getOperand(4))->getZExtValue(); > > + const PointerType *PTy = cast(CI.getOperand(1)->getType()); > > + const Type *MTy = PTy->getElementType(); > > + PointerType *NewPtrTy = NULL; > > + if (MTy == Type::Int8Ty) { > > + if (Size == 8) > > + NewPtrTy = PointerType::get(Type::Int64Ty); > > + else if (Size == 4) > > + NewPtrTy = PointerType::get(Type::Int32Ty); > > + else if (Size == 2) > > + NewPtrTy = PointerType::get(Type::Int16Ty); > > + else if (Size == 1) > > + NewPtrTy = PointerType::get(Type::Int8Ty); > > + } else if (MTy == Type::Int16Ty) { > > + if (Size == 4) > > + NewPtrTy = PointerType::get(Type::Int64Ty); > > + else if (Size == 2) > > + NewPtrTy = PointerType::get(Type::Int32Ty); > > + else if (Size == 1) > > + NewPtrTy = PointerType::get(Type::Int16Ty); > > + } else if (MTy == Type::Int32Ty) { > > + if (Size == 2) > > + NewPtrTy = PointerType::get(Type::Int64Ty); > > + else if (Size == 1) > > + NewPtrTy = PointerType::get(Type::Int32Ty); > > + } else if (MTy == Type::Int64Ty) { > > + if (Size == 1) > > + NewPtrTy = PointerType::get(Type::Int64Ty); > > + } > > It'd be great it this worked for non-scalar-integer types as well. > > Maybe you could do something like (warning, untested): > > if (Size == 1 && MTy->isFirstClassType()) > NewPtrTy = PointerType::get(MTy) > else { > CopySize = Size * TD->getABITypeSizeInBits(MTy); > if (CopySize == 8 || CopySize == 4 || CopySize == 2 || CopySize == 1) > NewPtrTy = PointerType::get(IntegerType::get(CopySize)); > } > > ? Oops, looking at this a little more, isn't the Size operand always in straight bytes, and MTy always i8, just because of how llvm.memcpy is declared? Also, this code can be used for memmove as well as memcpy; since the load grabs the entire source before anything is stored, overlap cases would work correctly. Dan -- Dan Gohman, Cray Inc. From djg at cray.com Thu Oct 11 18:04:39 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 11 Oct 2007 23:04:39 -0000 Subject: [llvm-commits] [llvm] r42878 - /llvm/trunk/test/CodeGen/X86/2007-09-17-ObjcFrameEH.ll Message-ID: <200710112304.l9BN4efk008270@zion.cs.uiuc.edu> Author: djg Date: Thu Oct 11 18:04:36 2007 New Revision: 42878 URL: http://llvm.org/viewvc/llvm-project?rev=42878&view=rev Log: Add an explicit target triple to make this test behave as expected on non-Apple hosts. And use the count script instead of wc + grep. Modified: llvm/trunk/test/CodeGen/X86/2007-09-17-ObjcFrameEH.ll Modified: llvm/trunk/test/CodeGen/X86/2007-09-17-ObjcFrameEH.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-09-17-ObjcFrameEH.ll?rev=42878&r1=42877&r2=42878&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-09-17-ObjcFrameEH.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-09-17-ObjcFrameEH.ll Thu Oct 11 18:04:36 2007 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 -enable-eh | grep {isNullOrNil].eh"} | wc -l | grep 2 +; RUN: llvm-as < %s | llc -march=x86 -mtriple=i686-apple-darwin -enable-eh | grep {isNullOrNil].eh"} | count 2 %struct.NSString = type { } %struct._objc__method_prototype_list = type opaque From djg at cray.com Thu Oct 11 18:06:38 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 11 Oct 2007 23:06:38 -0000 Subject: [llvm-commits] [llvm] r42879 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200710112306.l9BN6ce1008369@zion.cs.uiuc.edu> Author: djg Date: Thu Oct 11 18:06:37 2007 New Revision: 42879 URL: http://llvm.org/viewvc/llvm-project?rev=42879&view=rev Log: Add an ISD::FPOW node type. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=42879&r1=42878&r2=42879&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Oct 11 18:06:37 2007 @@ -408,10 +408,10 @@ // conversions, but that is a noop, deleted by getNode(). BIT_CONVERT, - // FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI - Perform unary floating point - // negation, absolute value, square root, sine and cosine, and powi + // FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW - Perform unary floating point + // negation, absolute value, square root, sine and cosine, powi, and pow // operations. - FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, + FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, // LOAD and STORE have token chains as their first operand, then the same // operands as an LLVM load/store instruction, then an offset node that Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=42879&r1=42878&r2=42879&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Oct 11 18:06:37 2007 @@ -3602,6 +3602,7 @@ case ISD::FSIN: return "fsin"; case ISD::FCOS: return "fcos"; case ISD::FPOWI: return "fpowi"; + case ISD::FPOW: return "fpow"; // Binary operators case ISD::ADD: return "add"; From djg at cray.com Thu Oct 11 18:09:11 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 11 Oct 2007 23:09:11 -0000 Subject: [llvm-commits] [llvm] r42880 - in /llvm/trunk: include/llvm/CodeGen/RuntimeLibcalls.h lib/CodeGen/SelectionDAG/TargetLowering.cpp Message-ID: <200710112309.l9BN9B7v008453@zion.cs.uiuc.edu> Author: djg Date: Thu Oct 11 18:09:10 2007 New Revision: 42880 URL: http://llvm.org/viewvc/llvm-project?rev=42880&view=rev Log: Add runtime library names for pow. Modified: llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Modified: llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h?rev=42880&r1=42879&r2=42880&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h (original) +++ llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h Thu Oct 11 18:09:10 2007 @@ -72,6 +72,10 @@ SIN_F64, COS_F32, COS_F64, + POW_F32, + POW_F64, + POW_F80, + POW_PPCF128, // CONVERSION FPEXT_F32_F64, Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=42880&r1=42879&r2=42880&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Thu Oct 11 18:09:10 2007 @@ -73,6 +73,10 @@ Names[RTLIB::SIN_F64] = "sin"; Names[RTLIB::COS_F32] = "cosf"; Names[RTLIB::COS_F64] = "cos"; + Names[RTLIB::POW_F32] = "powf"; + Names[RTLIB::POW_F64] = "pow"; + Names[RTLIB::POW_F80] = "powl"; + Names[RTLIB::POW_PPCF128] = "powl"; Names[RTLIB::FPEXT_F32_F64] = "__extendsfdf2"; Names[RTLIB::FPROUND_F64_F32] = "__truncdfsf2"; Names[RTLIB::FPTOSINT_F32_I32] = "__fixsfsi"; From djg at cray.com Thu Oct 11 18:21:31 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 11 Oct 2007 23:21:31 -0000 Subject: [llvm-commits] [llvm] r42881 - in /llvm/trunk/lib/Target: ARM/ARMISelLowering.cpp Alpha/AlphaISelLowering.cpp IA64/IA64ISelLowering.cpp PowerPC/PPCISelLowering.cpp Sparc/SparcISelDAGToDAG.cpp X86/X86ISelLowering.cpp Message-ID: <200710112321.l9BNLWcX008974@zion.cs.uiuc.edu> Author: djg Date: Thu Oct 11 18:21:31 2007 New Revision: 42881 URL: http://llvm.org/viewvc/llvm-project?rev=42881&view=rev Log: Set ISD::FPOW to Expand. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=42881&r1=42880&r2=42881&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu Oct 11 18:21:31 2007 @@ -240,7 +240,7 @@ setOperationAction(ISD::ConstantFP, MVT::f64, Expand); setOperationAction(ISD::ConstantFP, MVT::f32, Expand); - // We don't support sin/cos/fmod/copysign + // We don't support sin/cos/fmod/copysign/pow setOperationAction(ISD::FSIN , MVT::f64, Expand); setOperationAction(ISD::FSIN , MVT::f32, Expand); setOperationAction(ISD::FCOS , MVT::f32, Expand); @@ -249,6 +249,8 @@ setOperationAction(ISD::FREM , MVT::f32, Expand); setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom); + setOperationAction(ISD::FPOW , MVT::f64, Expand); + setOperationAction(ISD::FPOW , MVT::f32, Expand); // int <-> fp are custom expanded into bit_convert + ARMISD ops. setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp?rev=42881&r1=42880&r2=42881&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp Thu Oct 11 18:21:31 2007 @@ -93,7 +93,7 @@ setOperationAction(ISD::MEMSET , MVT::Other, Expand); setOperationAction(ISD::MEMCPY , MVT::Other, Expand); - // We don't support sin/cos/sqrt + // We don't support sin/cos/sqrt/pow setOperationAction(ISD::FSIN , MVT::f64, Expand); setOperationAction(ISD::FCOS , MVT::f64, Expand); setOperationAction(ISD::FSIN , MVT::f32, Expand); @@ -101,6 +101,9 @@ setOperationAction(ISD::FSQRT, MVT::f64, Expand); setOperationAction(ISD::FSQRT, MVT::f32, Expand); + + setOperationAction(ISD::FPOW , MVT::f32, Expand); + setOperationAction(ISD::FPOW , MVT::f64, Expand); setOperationAction(ISD::SETCC, MVT::f32, Promote); Modified: llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp?rev=42881&r1=42880&r2=42881&view=diff ============================================================================== --- llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp Thu Oct 11 18:21:31 2007 @@ -73,13 +73,15 @@ setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote); setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote); - // We don't support sin/cos/sqrt + // We don't support sin/cos/sqrt/pow setOperationAction(ISD::FSIN , MVT::f64, Expand); setOperationAction(ISD::FCOS , MVT::f64, Expand); setOperationAction(ISD::FSQRT, MVT::f64, Expand); + setOperationAction(ISD::FPOW , MVT::f64, Expand); setOperationAction(ISD::FSIN , MVT::f32, Expand); setOperationAction(ISD::FCOS , MVT::f32, Expand); setOperationAction(ISD::FSQRT, MVT::f32, Expand); + setOperationAction(ISD::FPOW , MVT::f32, Expand); // FIXME: IA64 supports fcopysign natively! setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=42881&r1=42880&r2=42881&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Thu Oct 11 18:21:31 2007 @@ -101,13 +101,15 @@ setOperationAction(ISD::UDIVREM, MVT::i64, Expand); setOperationAction(ISD::SDIVREM, MVT::i64, Expand); - // We don't support sin/cos/sqrt/fmod + // We don't support sin/cos/sqrt/fmod/pow setOperationAction(ISD::FSIN , MVT::f64, Expand); setOperationAction(ISD::FCOS , MVT::f64, Expand); setOperationAction(ISD::FREM , MVT::f64, Expand); + setOperationAction(ISD::FPOW , MVT::f64, Expand); setOperationAction(ISD::FSIN , MVT::f32, Expand); setOperationAction(ISD::FCOS , MVT::f32, Expand); setOperationAction(ISD::FREM , MVT::f32, Expand); + setOperationAction(ISD::FPOW , MVT::f32, Expand); // If we're enabling GP optimizations, use hardware square root if (!TM.getSubtarget().hasFSQRT()) { Modified: llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp?rev=42881&r1=42880&r2=42881&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp Thu Oct 11 18:21:31 2007 @@ -205,6 +205,8 @@ setOperationAction(ISD::BSWAP, MVT::i32, Expand); setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand); + setOperationAction(ISD::FPOW , MVT::f64, Expand); + setOperationAction(ISD::FPOW , MVT::f32, Expand); setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=42881&r1=42880&r2=42881&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Oct 11 18:21:31 2007 @@ -440,6 +440,11 @@ setOperationAction(ISD::FCOS , MVT::f80 , Expand); } + // Always use a library call for pow. + setOperationAction(ISD::FPOW , MVT::f32 , Expand); + setOperationAction(ISD::FPOW , MVT::f64 , Expand); + setOperationAction(ISD::FPOW , MVT::f80 , Expand); + // First set operation action for all vector types to expand. Then we // will selectively turn on ones that can be effectively codegen'd. for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE; @@ -471,6 +476,7 @@ setOperationAction(ISD::UMUL_LOHI, (MVT::ValueType)VT, Expand); setOperationAction(ISD::SDIVREM, (MVT::ValueType)VT, Expand); setOperationAction(ISD::UDIVREM, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::FPOW, (MVT::ValueType)VT, Expand); } if (Subtarget->hasMMX()) { From dalej at apple.com Thu Oct 11 18:32:15 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 11 Oct 2007 23:32:15 -0000 Subject: [llvm-commits] [llvm] r42882 - in /llvm/trunk/lib/CodeGen: AsmPrinter.cpp SelectionDAG/LegalizeDAG.cpp Message-ID: <200710112332.l9BNWFLD009395@zion.cs.uiuc.edu> Author: johannes Date: Thu Oct 11 18:32:15 2007 New Revision: 42882 URL: http://llvm.org/viewvc/llvm-project?rev=42882&view=rev Log: Implement ppc long double->uint conversion. Make ppc long double constants print. Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter.cpp?rev=42882&r1=42881&r2=42882&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Thu Oct 11 18:32:15 2007 @@ -917,6 +917,39 @@ << " long double most significant halfword\n"; } return; + } else if (CFP->getType() == Type::PPC_FP128Ty) { + // all long double variants are printed as hex + // api needed to prevent premature destruction + APInt api = CFP->getValueAPF().convertToAPInt(); + const uint64_t *p = api.getRawData(); + if (TD->isBigEndian()) { + O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32) + << "\t" << TAI->getCommentString() + << " long double most significant word\n"; + O << TAI->getData32bitsDirective() << uint32_t(p[0]) + << "\t" << TAI->getCommentString() + << " long double next word\n"; + O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32) + << "\t" << TAI->getCommentString() + << " long double next word\n"; + O << TAI->getData32bitsDirective() << uint32_t(p[1]) + << "\t" << TAI->getCommentString() + << " long double least significant word\n"; + } else { + O << TAI->getData32bitsDirective() << uint32_t(p[1]) + << "\t" << TAI->getCommentString() + << " long double least significant word\n"; + O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32) + << "\t" << TAI->getCommentString() + << " long double next word\n"; + O << TAI->getData32bitsDirective() << uint32_t(p[0]) + << "\t" << TAI->getCommentString() + << " long double next word\n"; + O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32) + << "\t" << TAI->getCommentString() + << " long double most significant word\n"; + } + return; } else assert(0 && "Floating point constant type not handled"); } else if (CV->getType() == Type::Int64Ty) { if (const ConstantInt *CI = dyn_cast(CV)) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=42882&r1=42881&r2=42882&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Oct 11 18:32:15 2007 @@ -3322,17 +3322,35 @@ } break; case Expand: { - // Convert f32 / f64 to i32 / i64. MVT::ValueType VT = Op.getValueType(); MVT::ValueType OVT = Node->getOperand(0).getValueType(); + // Convert ppcf128 to i32 if (OVT == MVT::ppcf128 && VT == MVT::i32) { - Result = DAG.getNode(ISD::FP_TO_SINT, VT, + if (Node->getOpcode()==ISD::FP_TO_SINT) + Result = DAG.getNode(ISD::FP_TO_SINT, VT, DAG.getNode(ISD::FP_ROUND, MVT::f64, (DAG.getNode(ISD::FP_ROUND_INREG, MVT::ppcf128, Node->getOperand(0), DAG.getValueType(MVT::f64))))); + else { + const uint64_t TwoE31[] = {0x41e0000000000000LL, 0}; + APFloat apf = APFloat(APInt(128, 2, TwoE31)); + Tmp2 = DAG.getConstantFP(apf, OVT); + // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X + // FIXME: generated code sucks. + Result = DAG.getNode(ISD::SELECT_CC, VT, Node->getOperand(0), Tmp2, + DAG.getNode(ISD::ADD, MVT::i32, + DAG.getNode(ISD::FP_TO_SINT, VT, + DAG.getNode(ISD::FSUB, OVT, + Node->getOperand(0), Tmp2)), + DAG.getConstant(0x80000000, MVT::i32)), + DAG.getNode(ISD::FP_TO_SINT, VT, + Node->getOperand(0)), + DAG.getCondCode(ISD::SETGE)); + } break; } + // Convert f32 / f64 to i32 / i64. RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; switch (Node->getOpcode()) { case ISD::FP_TO_SINT: { @@ -5170,7 +5188,11 @@ if (VT == MVT::ppcf128 && TLI.getOperationAction(ISD::FP_ROUND_INREG, VT) == TargetLowering::Custom) { - SDOperand Result = TLI.LowerOperation(Op, DAG); + SDOperand SrcLo, SrcHi, Src; + ExpandOp(Op.getOperand(0), SrcLo, SrcHi); + Src = DAG.getNode(ISD::BUILD_PAIR, VT, SrcLo, SrcHi); + SDOperand Result = TLI.LowerOperation( + DAG.getNode(ISD::FP_ROUND_INREG, VT, Src, Op.getOperand(1)), DAG); assert(Result.Val->getOpcode() == ISD::BUILD_PAIR); Lo = Result.Val->getOperand(0); Hi = Result.Val->getOperand(1); From dpatel at apple.com Thu Oct 11 18:56:16 2007 From: dpatel at apple.com (Devang Patel) Date: Thu, 11 Oct 2007 16:56:16 -0700 Subject: [llvm-commits] [llvm] r42864 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll In-Reply-To: <20071011220855.GB21991@village.us.cray.com> References: <20071011220855.GB21991@village.us.cray.com> Message-ID: On Oct 11, 2007, at 3:08 PM, Dan Gohman wrote: >> + ConstantInt *MemOpLength = >> dyn_cast(CI.getOperand(3)); >> + if (isa(MI)) >> + if (MemOpLength) { > > Can you replace these two if statements with > > if (isa(MI) && MemOpLength) { > > ? > > Then the indentation of what follows won't be wrong either :-) OK. I don't know why I did it this way. - Devang From djg at cray.com Thu Oct 11 18:57:53 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 11 Oct 2007 23:57:53 -0000 Subject: [llvm-commits] [llvm] r42884 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200710112357.l9BNvrt9010949@zion.cs.uiuc.edu> Author: djg Date: Thu Oct 11 18:57:53 2007 New Revision: 42884 URL: http://llvm.org/viewvc/llvm-project?rev=42884&view=rev Log: Codegen support for vector intrinsics. Factor out the code that expands the "nasty scalar code" for unrolling vectors into a separate routine, teach it how to handle mixed vector/scalar operands, as seen in powi, and use it for several operators, including sin, cos, powi, and pow. Add support in SplitVectorOp for fpow, fpowi and for several unary operators. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=42884&r1=42883&r2=42884&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Oct 11 18:57:53 2007 @@ -147,6 +147,12 @@ /// result. SDOperand LegalizeOp(SDOperand O); + /// UnrollVectorOp - We know that the given vector has a legal type, however + /// the operation it performs is not legal and is an operation that we have + /// no way of lowering. "Unroll" the vector, splitting out the scalars and + /// operating on each element individually. + SDOperand UnrollVectorOp(SDOperand O); + /// PromoteOp - Given an operation that produces a value in an invalid type, /// promote it to compute the value into a larger type. The produced value /// will have the correct bits for the low portion of the register, but no @@ -679,6 +685,44 @@ return DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(VT, MVT::Other), Ops, 2); } +/// UnrollVectorOp - We know that the given vector has a legal type, however +/// the operation it performs is not legal and is an operation that we have +/// no way of lowering. "Unroll" the vector, splitting out the scalars and +/// operating on each element individually. +SDOperand SelectionDAGLegalize::UnrollVectorOp(SDOperand Op) { + MVT::ValueType VT = Op.getValueType(); + assert(isTypeLegal(VT) && + "Caller should expand or promote operands that are not legal!"); + assert(Op.Val->getNumValues() == 1 && + "Can't unroll a vector with multiple results!"); + unsigned NE = MVT::getVectorNumElements(VT); + MVT::ValueType EltVT = MVT::getVectorElementType(VT); + + SmallVector Scalars; + SmallVector Operands(Op.getNumOperands()); + for (unsigned i = 0; i != NE; ++i) { + for (unsigned j = 0; j != Op.getNumOperands(); ++j) { + SDOperand Operand = Op.getOperand(j); + MVT::ValueType OperandVT = Operand.getValueType(); + if (MVT::isVector(OperandVT)) { + // A vector operand; extract a single element. + MVT::ValueType OperandEltVT = MVT::getVectorElementType(OperandVT); + Operands[j] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, + OperandEltVT, + Operand, + DAG.getConstant(i, MVT::i32)); + } else { + // A scalar operand; just use it as is. + Operands[j] = Operand; + } + } + Scalars.push_back(DAG.getNode(Op.getOpcode(), EltVT, + &Operands[0], Operands.size())); + } + + return DAG.getNode(ISD::BUILD_VECTOR, VT, &Scalars[0], Scalars.size()); +} + /// LegalizeOp - We know that the specified value has a legal type, and /// that its operands are legal. Now ensure that the operation itself /// is legal, recursively ensuring that the operands' operations remain @@ -2556,6 +2600,7 @@ case ISD::FSUB: case ISD::FMUL: case ISD::FDIV: + case ISD::FPOW: Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS switch (getTypeAction(Node->getOperand(1).getValueType())) { case Expand: assert(0 && "Not possible"); @@ -2626,35 +2671,37 @@ break; } - if (Node->getValueType(0) == MVT::i32) { - switch (Node->getOpcode()) { - default: assert(0 && "Do not know how to expand this integer BinOp!"); - case ISD::UDIV: - case ISD::SDIV: - RTLIB::Libcall LC = Node->getOpcode() == ISD::UDIV + // Check to see if we have a libcall for this operator. + RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; + bool isSigned = false; + switch (Node->getOpcode()) { + case ISD::UDIV: + case ISD::SDIV: + if (VT == MVT::i32) { + LC = Node->getOpcode() == ISD::UDIV ? RTLIB::UDIV_I32 : RTLIB::SDIV_I32; - SDOperand Dummy; - bool isSigned = Node->getOpcode() == ISD::SDIV; - Result = ExpandLibCall(TLI.getLibcallName(LC), Node, isSigned, Dummy); - }; + isSigned = Node->getOpcode() == ISD::SDIV; + } + break; + case ISD::FPOW: + LC = VT == MVT::f32 ? RTLIB::POW_F32 : + VT == MVT::f64 ? RTLIB::POW_F64 : + VT == MVT::f80 ? RTLIB::POW_F80 : + VT == MVT::ppcf128 ? RTLIB::POW_PPCF128 : + RTLIB::UNKNOWN_LIBCALL; + break; + default: break; + } + if (LC != RTLIB::UNKNOWN_LIBCALL) { + SDOperand Dummy; + Result = ExpandLibCall(TLI.getLibcallName(LC), Node, isSigned, Dummy); break; } assert(MVT::isVector(Node->getValueType(0)) && "Cannot expand this binary operator!"); // Expand the operation into a bunch of nasty scalar code. - SmallVector Ops; - MVT::ValueType EltVT = MVT::getVectorElementType(Node->getValueType(0)); - MVT::ValueType PtrVT = TLI.getPointerTy(); - for (unsigned i = 0, e = MVT::getVectorNumElements(Node->getValueType(0)); - i != e; ++i) { - SDOperand Idx = DAG.getConstant(i, PtrVT); - SDOperand LHS = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Tmp1, Idx); - SDOperand RHS = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Tmp2, Idx); - Ops.push_back(DAG.getNode(Node->getOpcode(), EltVT, LHS, RHS)); - } - Result = DAG.getNode(ISD::BUILD_VECTOR, Node->getValueType(0), - &Ops[0], Ops.size()); + Result = LegalizeOp(UnrollVectorOp(Op)); break; } case TargetLowering::Promote: { @@ -3119,6 +3166,13 @@ case ISD::FSIN: case ISD::FCOS: { MVT::ValueType VT = Node->getValueType(0); + + // Expand unsupported unary vector operators by unrolling them. + if (MVT::isVector(VT)) { + Result = LegalizeOp(UnrollVectorOp(Op)); + break; + } + RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; switch(Node->getOpcode()) { case ISD::FSQRT: @@ -3146,12 +3200,20 @@ } break; case ISD::FPOWI: { - // We always lower FPOWI into a libcall. No target support it yet. + MVT::ValueType VT = Node->getValueType(0); + + // Expand unsupported unary vector operators by unrolling them. + if (MVT::isVector(VT)) { + Result = LegalizeOp(UnrollVectorOp(Op)); + break; + } + + // We always lower FPOWI into a libcall. No target support for it yet. RTLIB::Libcall LC = - Node->getValueType(0) == MVT::f32 ? RTLIB::POWI_F32 : - Node->getValueType(0) == MVT::f64 ? RTLIB::POWI_F64 : - Node->getValueType(0) == MVT::f80 ? RTLIB::POWI_F80 : - Node->getValueType(0) == MVT::ppcf128 ? RTLIB::POWI_PPCF128 : + VT == MVT::f32 ? RTLIB::POWI_F32 : + VT == MVT::f64 ? RTLIB::POWI_F64 : + VT == MVT::f80 ? RTLIB::POWI_F80 : + VT == MVT::ppcf128 ? RTLIB::POWI_PPCF128 : RTLIB::UNKNOWN_LIBCALL; SDOperand Dummy; Result = ExpandLibCall(TLI.getLibcallName(LC), Node, @@ -6095,6 +6157,7 @@ case ISD::SDIV: case ISD::UDIV: case ISD::FDIV: + case ISD::FPOW: case ISD::AND: case ISD::OR: case ISD::XOR: { @@ -6106,6 +6169,29 @@ Hi = DAG.getNode(Node->getOpcode(), NewVT, LH, RH); break; } + case ISD::FPOWI: { + SDOperand L, H; + SplitVectorOp(Node->getOperand(0), L, H); + + Lo = DAG.getNode(Node->getOpcode(), NewVT, L, Node->getOperand(1)); + Hi = DAG.getNode(Node->getOpcode(), NewVT, H, Node->getOperand(1)); + break; + } + case ISD::CTTZ: + case ISD::CTLZ: + case ISD::CTPOP: + case ISD::FNEG: + case ISD::FABS: + case ISD::FSQRT: + case ISD::FSIN: + case ISD::FCOS: { + SDOperand L, H; + SplitVectorOp(Node->getOperand(0), L, H); + + Lo = DAG.getNode(Node->getOpcode(), NewVT, L); + Hi = DAG.getNode(Node->getOpcode(), NewVT, H); + break; + } case ISD::LOAD: { LoadSDNode *LD = cast(Node); SDOperand Ch = LD->getChain(); @@ -6196,6 +6282,7 @@ case ISD::SREM: case ISD::UREM: case ISD::FREM: + case ISD::FPOW: case ISD::AND: case ISD::OR: case ISD::XOR: From dpatel at apple.com Thu Oct 11 18:59:26 2007 From: dpatel at apple.com (Devang Patel) Date: Thu, 11 Oct 2007 16:59:26 -0700 Subject: [llvm-commits] [llvm] r42864 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll In-Reply-To: <20071011222630.GC21991@village.us.cray.com> References: <20071011220855.GB21991@village.us.cray.com> <20071011222630.GC21991@village.us.cray.com> Message-ID: <168B73EB-EC02-4D7E-8406-A73CB462F4DD@apple.com> On Oct 11, 2007, at 3:26 PM, Dan Gohman wrote: > Oops, looking at this a little more, isn't the Size operand always in > straight bytes, and MTy always i8, just because of how llvm.memcpy is > declared? yes. nice catch! > Also, this code can be used for memmove as well as memcpy; since the > load > grabs the entire source before anything is stored, overlap cases > would work > correctly. yes - Devang From djg at cray.com Thu Oct 11 19:01:22 2007 From: djg at cray.com (Dan Gohman) Date: Fri, 12 Oct 2007 00:01:22 -0000 Subject: [llvm-commits] [llvm] r42885 - in /llvm/trunk: include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/X86/vector-intrinsics.ll Message-ID: <200710120001.l9C01MnW011262@zion.cs.uiuc.edu> Author: djg Date: Thu Oct 11 19:01:22 2007 New Revision: 42885 URL: http://llvm.org/viewvc/llvm-project?rev=42885&view=rev Log: Add intrinsics for sin, cos, and pow. These use llvm_anyfloat_ty, and so may be overloaded with vector types. And add a testcase for codegen for these. Added: llvm/trunk/test/CodeGen/X86/vector-intrinsics.ll Modified: llvm/trunk/include/llvm/Intrinsics.td llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=42885&r1=42884&r2=42885&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Thu Oct 11 19:01:22 2007 @@ -184,6 +184,10 @@ let Properties = [IntrNoMem] in { def int_sqrt : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>; def int_powi : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>, llvm_i32_ty]>; + def int_sin : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>; + def int_cos : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>; + def int_pow : Intrinsic<[llvm_anyfloat_ty, + LLVMMatchType<0>, LLVMMatchType<0>]>; } // NOTE: these are internal interfaces. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=42885&r1=42884&r2=42885&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Oct 11 19:01:22 2007 @@ -2807,6 +2807,22 @@ getValue(I.getOperand(1)), getValue(I.getOperand(2)))); return 0; + case Intrinsic::sin: + setValue(&I, DAG.getNode(ISD::FSIN, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)))); + return 0; + case Intrinsic::cos: + setValue(&I, DAG.getNode(ISD::FCOS, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)))); + return 0; + case Intrinsic::pow: + setValue(&I, DAG.getNode(ISD::FPOW, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)), + getValue(I.getOperand(2)))); + return 0; case Intrinsic::pcmarker: { SDOperand Tmp = getValue(I.getOperand(1)); DAG.setRoot(DAG.getNode(ISD::PCMARKER, MVT::Other, getRoot(), Tmp)); Added: llvm/trunk/test/CodeGen/X86/vector-intrinsics.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vector-intrinsics.ll?rev=42885&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/vector-intrinsics.ll (added) +++ llvm/trunk/test/CodeGen/X86/vector-intrinsics.ll Thu Oct 11 19:01:22 2007 @@ -0,0 +1,27 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | grep call | count 16 + +declare <4 x double> @llvm.sin.v4f64(<4 x double> %p) +declare <4 x double> @llvm.cos.v4f64(<4 x double> %p) +declare <4 x double> @llvm.pow.v4f64(<4 x double> %p, <4 x double> %q) +declare <4 x double> @llvm.powi.v4f64(<4 x double> %p, i32) + +define <4 x double> @foo(<4 x double> %p) +{ + %t = call <4 x double> @llvm.sin.v4f64(<4 x double> %p) + ret <4 x double> %t +} +define <4 x double> @goo(<4 x double> %p) +{ + %t = call <4 x double> @llvm.cos.v4f64(<4 x double> %p) + ret <4 x double> %t +} +define <4 x double> @moo(<4 x double> %p, <4 x double> %q) +{ + %t = call <4 x double> @llvm.pow.v4f64(<4 x double> %p, <4 x double> %q) + ret <4 x double> %t +} +define <4 x double> @zoo(<4 x double> %p, i32 %q) +{ + %t = call <4 x double> @llvm.powi.v4f64(<4 x double> %p, i32 %q) + ret <4 x double> %t +} From evan.cheng at apple.com Thu Oct 11 20:28:19 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 Oct 2007 18:28:19 -0700 Subject: [llvm-commits] [llvm] r42870 - in /llvm/trunk: include/llvm/Target/ lib/CodeGen/SelectionDAG/ lib/Target/ lib/Target/X86/ test/CodeGen/X86/ In-Reply-To: <200710111940.l9BJeCqc031930@zion.cs.uiuc.edu> References: <200710111940.l9BJeCqc031930@zion.cs.uiuc.edu> Message-ID: <4FB95CD4-B34F-42C7-8542-A4259D19E409@apple.com> Woot! Arnold, don't forget to update Makefile.programs to start testing it as x86 llcbeta. Thanks! Evan On Oct 11, 2007, at 12:40 PM, Arnold Schwaighofer wrote: > Author: arnolds > Date: Thu Oct 11 14:40:01 2007 > New Revision: 42870 > > URL: http://llvm.org/viewvc/llvm-project?rev=42870&view=rev > Log: > Added tail call optimization to the x86 back end. It can be > enabled by passing -tailcallopt to llc. The optimization is > performed if the following conditions are satisfied: > * caller/callee are fastcc > * elf/pic is disabled OR > elf/pic enabled + callee is in module + callee has > visibility protected or hidden > > Added: > llvm/trunk/test/CodeGen/X86/tailcall1.ll > llvm/trunk/test/CodeGen/X86/tailcallpic1.ll > llvm/trunk/test/CodeGen/X86/tailcallpic2.ll > Modified: > llvm/trunk/include/llvm/Target/TargetLowering.h > llvm/trunk/include/llvm/Target/TargetOptions.h > llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > llvm/trunk/lib/Target/TargetMachine.cpp > llvm/trunk/lib/Target/X86/README.txt > llvm/trunk/lib/Target/X86/X86CallingConv.td > llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > llvm/trunk/lib/Target/X86/X86ISelLowering.h > llvm/trunk/lib/Target/X86/X86InstrInfo.cpp > llvm/trunk/lib/Target/X86/X86InstrInfo.td > llvm/trunk/lib/Target/X86/X86InstrX86-64.td > llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h > llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp > > Modified: llvm/trunk/include/llvm/Target/TargetLowering.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=42870&r1=42869&r2=42870&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) > +++ llvm/trunk/include/llvm/Target/TargetLowering.h Thu Oct 11 > 14:40:01 2007 > @@ -860,6 +860,15 @@ > /// implement this. The default implementation of this aborts. > virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); > > + /// IsEligibleForTailCallOptimization - Check whether the call is > eligible for > + /// tail call optimization. Target which want to do tail call > optimization > + /// should implement this function. > + virtual bool IsEligibleForTailCallOptimization(SDOperand Call, > + SDOperand Ret, > + SelectionDAG &DAG) > const { > + return false; > + } > + > /// CustomPromoteOperation - This callback is invoked for > operations that are > /// unsupported by the target, are registered to use 'custom' > lowering, and > /// whose type needs to be promoted. > > Modified: llvm/trunk/include/llvm/Target/TargetOptions.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetOptions.h?rev=42870&r1=42869&r2=42870&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Target/TargetOptions.h (original) > +++ llvm/trunk/include/llvm/Target/TargetOptions.h Thu Oct 11 > 14:40:01 2007 > @@ -73,6 +73,11 @@ > /// ExceptionHandling - This flag indicates that exception > information should > /// be emitted. > extern bool ExceptionHandling; > + > + /// PerformTailCallOpt - This flag is enabled when the - > tailcallopt is > + /// specified on the commandline. When the flag is on, the target > will perform > + /// tail call optimization (pop the caller's stack) providing it > supports it. > + extern bool PerformTailCallOpt; > } // End llvm namespace > > #endif > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=42870&r1=42869&r2=42870&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Oct > 11 14:40:01 2007 > @@ -4444,6 +4444,48 @@ > } > } > > +/// CheckDAGForTailCallsAndFixThem - This Function looks for CALL > nodes in the > +/// DAG and fixes their tailcall attribute operand > +static void CheckDAGForTailCallsAndFixThem(SelectionDAG &DAG, > + TargetLowering& TLI) { > + SDNode * Ret = NULL; > + SDOperand Terminator = DAG.getRoot(); > + > + // Find RET node. > + if (Terminator.getOpcode() == ISD::RET) { > + Ret = Terminator.Val; > + } > + > + // Fix tail call attribute of CALL nodes. > + for (SelectionDAG::allnodes_iterator BE = DAG.allnodes_begin(), > + BI = prior(DAG.allnodes_end()); BI != BE; --BI) { > + if (BI->getOpcode() == ISD::CALL) { > + SDOperand OpRet(Ret, 0); > + SDOperand OpCall(static_cast(BI), 0); > + bool isMarkedTailCall = > + cast(OpCall.getOperand(3))->getValue() != 0; > + // If CALL node has tail call attribute set to true and the > call is not > + // eligible (no RET or the target rejects) the attribute is > fixed to > + // false. The > TargetLowering::IsEligibleForTailCallOptimization function > + // must correctly identify tail call optimizable calls. > + if (isMarkedTailCall && > + (Ret==NULL || > + !TLI.IsEligibleForTailCallOptimization(OpCall, OpRet, > DAG))) { > + SmallVector Ops; > + unsigned idx=0; > + for(SDNode::op_iterator I =OpCall.Val->op_begin(), > + E=OpCall.Val->op_end(); I!=E; I++, idx++) { > + if (idx!=3) > + Ops.push_back(*I); > + else > + Ops.push_back(DAG.getConstant(false, > TLI.getPointerTy())); > + } > + DAG.UpdateNodeOperands(OpCall, Ops.begin(), Ops.size()); > + } > + } > + } > +} > + > void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, > BasicBlock *LLVMBB, > std::vector > > &PHINodesToUpdate, > FunctionLoweringInfo > &FuncInfo) { > @@ -4621,6 +4663,12 @@ > > // Make sure the root of the DAG is up-to-date. > DAG.setRoot(SDL.getRoot()); > + > + // Check whether calls in this block are real tail calls. Fix up > CALL nodes > + // with correct tailcall attribute so that the target can rely on > the tailcall > + // attribute indicating whether the call is really eligible for > tail call > + // optimization. > + CheckDAGForTailCallsAndFixThem(DAG, TLI); > } > > void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) { > > Modified: llvm/trunk/lib/Target/TargetMachine.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetMachine.cpp?rev=42870&r1=42869&r2=42870&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/TargetMachine.cpp (original) > +++ llvm/trunk/lib/Target/TargetMachine.cpp Thu Oct 11 14:40:01 2007 > @@ -33,6 +33,7 @@ > bool ExceptionHandling; > Reloc::Model RelocationModel; > CodeModel::Model CMModel; > + bool PerformTailCallOpt; > } > namespace { > cl::opt PrintCode("print-machineinstrs", > @@ -116,6 +117,12 @@ > clEnumValN(CodeModel::Large, "large", > " Large code model"), > clEnumValEnd)); > + > + cl::opt > + EnablePerformTailCallOpt("tailcallopt", > + cl::desc("Turn on tail call > optimization."), > + cl::location(PerformTailCallOpt), > + cl::init(false)); > } > > //--------------------------------------------------------------------------- > > Modified: llvm/trunk/lib/Target/X86/README.txt > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=42870&r1=42869&r2=42870&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/README.txt (original) > +++ llvm/trunk/lib/Target/X86/README.txt Thu Oct 11 14:40:01 2007 > @@ -1368,3 +1368,83 @@ > L5: > > // > = > = > = > --------------------------------------------------------------------- > ===// > +Tail call optimization improvements: Tail call optimization currently > +pushes all arguments on the top of the stack (their normal place if > +that was a not tail call optimized functiong call ) before moving > them > +to actual stack slot. this is done to prevent overwriting of > paramters > +(see example below) that might be used, since the arguments of the > +callee overwrites callers arguments. > + > + example: > + > +int callee(int32, int64); > +int caller(int32 arg1, int32 arg2) { > + int64 local = arg2 * 2; > + return callee(arg2, (int64)local); > +} > + > +[arg1] [!arg2 no longer valid since we moved local onto it] > +[arg2] -> [(int64) > +[RETADDR] local ] > + > +moving arg1 onto the stack slot of callee function would overwrite > +arg2 of the caller. > + > +Possible optimizations: > + > + - only push those arguments to the top of the stack that are actual > + parameters of the caller function and have no local value in the > + caller > + > + in above example local does not need to be pushed onto the top of > + the stack as it is definitetly not a caller's function parameter > + > + - analyse the actual parameters of the callee to see which would > + overwrite a caller paramter which is used by the callee and only > + push them onto the top of the stack > + > + int callee (int32 arg1, int32 arg2); > + int caller (int32 arg1, int32 arg2) { > + return callee(arg1,arg2); > + } > + > + here we don't need to write any variables to the top of the stack > + since they don't overwrite each other > + > + int callee (int32 arg1, int32 arg2); > + int caller (int32 arg1, int32 arg2) { > + return callee(arg2,arg1); > + } > + > + here we need to push the arguments because they overwrite each > other > + > + > + code for lowering directly onto callers arguments: > ++ SmallVector, 8> RegsToPass; > ++ SmallVector MemOpChains; > ++ > ++ SDOperand FramePtr; > ++ SDOperand PtrOff; > ++ SDOperand FIN; > ++ int FI = 0; > ++ // Walk the register/memloc assignments, inserting copies/loads. > ++ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { > ++ CCValAssign &VA = ArgLocs[i]; > ++ SDOperand Arg = Op.getOperand(5+2*VA.getValNo()); > ++ > ++ .... > ++ > ++ if (VA.isRegLoc()) { > ++ RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); > ++ } else { > ++ assert(VA.isMemLoc()); > ++ // create frame index > ++ int32_t Offset = VA.getLocMemOffset()+FPDiff; > ++ uint32_t OpSize = (MVT::getSizeInBits(VA.getLocVT())+7)/8; > ++ FI = MF.getFrameInfo()->CreateFixedObject(OpSize, Offset); > ++ FIN = DAG.getFrameIndex(FI, MVT::i32); > ++ // store relative to framepointer > ++ MemOpChains.push_back(DAG.getStore(Chain, Arg, FIN, NULL, 0)); > ++ } > ++ } > +// > = > = > = > --------------------------------------------------------------------- > ===// > > Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallingConv.td?rev=42870&r1=42869&r2=42870&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86CallingConv.td (original) > +++ llvm/trunk/lib/Target/X86/X86CallingConv.td Thu Oct 11 14:40:01 > 2007 > @@ -127,6 +127,40 @@ > CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToStack<8, 8>> > ]>; > > +// tail call convetion (fast) one register is reserved for target > address > +// namely R9 > +def CC_X86_64_TailCall : CallingConv<[ > + // Promote i8/i16 arguments to i32. > + CCIfType<[i8, i16], CCPromoteToType>, > + > + CCIfStruct>, > + > + // The first 6 integer arguments are passed in integer registers. > + CCIfType<[i32], CCAssignToReg<[EDI, ESI, EDX, ECX, R8D]>>, > + CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8]>>, > + > + // The first 8 FP/Vector arguments are passed in XMM registers. > + CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], > + CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, > XMM6, XMM7]>>, > + > + // The first 8 MMX vector arguments are passed in GPRs. > + CCIfType<[v8i8, v4i16, v2i32, v1i64], > + CCAssignToReg<[RDI, RSI, RDX, RCX, R8]>>, > + > + // The 'nest' parameter, if any, is passed in R10. > + CCIfNest>, > + > + // Integer/FP values get stored in stack slots that are 8 bytes > in size and > + // 8-byte aligned if there are no more registers to hold them. > + CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>, > + > + // Vectors get 16-byte stack slots that are 16-byte aligned. > + CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], > CCAssignToStack<16, 16>>, > + > + // __m64 vectors get 8-byte stack slots that are 8-byte aligned. > + CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToStack<8, 8>> > +]>; > + > > // > = > = > = > ----------------------------------------------------------------------= > ==// > // X86 C Calling Convention > @@ -173,6 +207,22 @@ > CCDelegateTo > ]>; > > +/// Same as C calling convention up to nonfree ECX which is used > for storing > +/// potential pointer to tail called function > +def CC_X86_32_TailCall : CallingConv<[ > + // Promote i8/i16 arguments to i32. > + CCIfType<[i8, i16], CCPromoteToType>, > + > + // The 'nest' parameter, if any, is passed in ECX. > + CCIfNest>, > + > + // The first 3 integer arguments, if marked 'inreg' and if the > call is not > + // a vararg call, are passed in integer registers. > + CCIfNotVarArg EDX]>>>>, > + > + // Otherwise, same as everything else. > + CCDelegateTo > +]>; > > def CC_X86_32_FastCall : CallingConv<[ > // Promote i8/i16 arguments to i32. > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=42870&r1=42869&r2=42870&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Oct 11 > 14:40:01 2007 > @@ -32,6 +32,8 @@ > #include "llvm/CodeGen/SelectionDAG.h" > #include "llvm/CodeGen/SSARegMap.h" > #include "llvm/Support/MathExtras.h" > +#include "llvm/Support/CommandLine.h" > +#include "llvm/Support/Debug.h" > #include "llvm/Target/TargetOptions.h" > #include "llvm/ADT/StringExtras.h" > #include "llvm/ParameterAttributes.h" > @@ -43,6 +45,7 @@ > X86ScalarSSEf64 = Subtarget->hasSSE2(); > X86ScalarSSEf32 = Subtarget->hasSSE1(); > X86StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP; > + > > RegInfo = TM.getRegisterInfo(); > > @@ -641,6 +644,19 @@ > // > = > = > = > ----------------------------------------------------------------------= > ==// > > #include "X86GenCallingConv.inc" > + > +/// GetPossiblePreceedingTailCall - Get preceeding X86ISD::TAILCALL > node if it > +/// exists skip possible ISD:TokenFactor. > +static SDOperand GetPossiblePreceedingTailCall(SDOperand Chain) { > + if (Chain.getOpcode()==X86ISD::TAILCALL) { > + return Chain; > + } else if (Chain.getOpcode()==ISD::TokenFactor) { > + if (Chain.getNumOperands() && > + Chain.getOperand(0).getOpcode()==X86ISD::TAILCALL) > + return Chain.getOperand(0); > + } > + return Chain; > +} > > /// LowerRET - Lower an ISD::RET node. > SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG > &DAG) { > @@ -651,8 +667,7 @@ > bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); > CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs); > CCInfo.AnalyzeReturn(Op.Val, RetCC_X86); > - > - > + > // If this is the first return lowered for this function, add the > regs to the > // liveout set for the function. > if (DAG.getMachineFunction().liveout_empty()) { > @@ -660,10 +675,38 @@ > if (RVLocs[i].isRegLoc()) > DAG.getMachineFunction().addLiveOut(RVLocs[i].getLocReg()); > } > - > SDOperand Chain = Op.getOperand(0); > - SDOperand Flag; > > + // Handle tail call return. > + Chain = GetPossiblePreceedingTailCall(Chain); > + if (Chain.getOpcode() == X86ISD::TAILCALL) { > + SDOperand TailCall = Chain; > + SDOperand TargetAddress = TailCall.getOperand(1); > + SDOperand StackAdjustment = TailCall.getOperand(2); > + assert ( ((TargetAddress.getOpcode() == ISD::Register && > + (cast(TargetAddress)->getReg() == > X86::ECX || > + cast(TargetAddress)->getReg() == > X86::R9)) || > + TargetAddress.getOpcode() == > ISD::TargetExternalSymbol || > + TargetAddress.getOpcode() == > ISD::TargetGlobalAddress) && > + "Expecting an global address, external symbol, or > register"); > + assert( StackAdjustment.getOpcode() == ISD::Constant && > + "Expecting a const value"); > + > + SmallVector Operands; > + Operands.push_back(Chain.getOperand(0)); > + Operands.push_back(TargetAddress); > + Operands.push_back(StackAdjustment); > + // Copy registers used by the call. Last operand is a flag so > it is not > + // copied. > + for(unsigned i=3; i < TailCall.getNumOperands()-1;i++) { > + Operands.push_back(Chain.getOperand(i)); > + } > + return DAG.getNode(X86ISD::TC_RETURN, MVT::Other, &Operands[0], > Operands.size()); > + } > + > + // Regular return. > + SDOperand Flag; > + > // Copy the result values into the output registers. > if (RVLocs.size() != 1 || !RVLocs[0].isRegLoc() || > RVLocs[0].getLocReg() != X86::ST0) { > @@ -684,7 +727,7 @@ > if ((X86ScalarSSEf32 && RVLocs[0].getValVT()==MVT::f32) || > (X86ScalarSSEf64 && RVLocs[0].getValVT()==MVT::f64)) { > SDOperand MemLoc; > - > + > // If this is a load into a scalarsse value, don't store the > loaded value > // back to the stack, only to reload it: just replace the > scalar-sse load. > if (ISD::isNON_EXTLoad(Value.Val) && > @@ -784,12 +827,14 @@ > > > // > = > = > = > ----------------------------------------------------------------------= > ==// > -// C & StdCall Calling Convention implementation > +// C & StdCall & Fast Calling Convention > implementation > // > = > = > = > ----------------------------------------------------------------------= > ==// > // StdCall calling convention seems to be standard for many > Windows' API > // routines and around. It differs from C calling convention just a > little: > // callee should clean up the stack, not caller. Symbols should be > also > // decorated in some fancy way :) It doesn't support any vector > arguments. > +// For info on fast calling convention see Fast Calling Convention > (tail call) > +// implementation LowerX86_32FastCCCallTo. > > /// AddLiveIn - This helper function adds the specified physical > register to the > /// MachineFunction as a live in value. It also creates a > corresponding virtual > @@ -802,6 +847,9 @@ > return VReg; > } > > +// align stack arguments according to platform alignment needed for > tail calls > +unsigned GetAlignedArgumentStackSize(unsigned StackSize, > SelectionDAG& DAG); > + > SDOperand X86TargetLowering::LowerMemArgument(SDOperand Op, > SelectionDAG &DAG, > const CCValAssign &VA, > MachineFrameInfo *MFI, > @@ -826,13 +874,17 @@ > MachineFrameInfo *MFI = MF.getFrameInfo(); > SDOperand Root = Op.getOperand(0); > bool isVarArg = cast(Op.getOperand(2))- > >getValue() != 0; > - > + unsigned CC = MF.getFunction()->getCallingConv(); > // Assign locations to all of the incoming arguments. > SmallVector ArgLocs; > - CCState CCInfo(MF.getFunction()->getCallingConv(), isVarArg, > + CCState CCInfo(CC, isVarArg, > getTargetMachine(), ArgLocs); > - CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_32_C); > - > + // Check for possible tail call calling convention. > + if (CC == CallingConv::Fast && PerformTailCallOpt) > + CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_32_TailCall); > + else > + CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_32_C); > + > SmallVector ArgValues; > unsigned LastVal = ~0U; > for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { > @@ -877,6 +929,9 @@ > } > > unsigned StackSize = CCInfo.getNextStackOffset(); > + // align stack specially for tail calls > + if (CC==CallingConv::Fast) > + StackSize = GetAlignedArgumentStackSize(StackSize,DAG); > > ArgValues.push_back(Root); > > @@ -885,7 +940,12 @@ > if (isVarArg) > VarArgsFrameIndex = MFI->CreateFixedObject(1, StackSize); > > - if (isStdCall && !isVarArg) { > + // Tail call calling convention (CallingConv::Fast) does not > support varargs. > + assert( !(isVarArg && CC == CallingConv::Fast) && > + "CallingConv::Fast does not support varargs."); > + > + if (isStdCall && !isVarArg && > + (CC==CallingConv::Fast && PerformTailCallOpt || CC! > =CallingConv::Fast)) { > BytesToPopOnReturn = StackSize; // Callee pops everything.. > BytesCallerReserves = 0; > } else { > @@ -914,17 +974,21 @@ > unsigned CC) { > SDOperand Chain = Op.getOperand(0); > bool isVarArg = cast(Op.getOperand(2))- > >getValue() != 0; > - bool isTailCall = cast(Op.getOperand(3))- > >getValue() != 0; > SDOperand Callee = Op.getOperand(4); > unsigned NumOps = (Op.getNumOperands() - 5) / 2; > - > + > // Analyze operands of the call, assigning locations to each > operand. > SmallVector ArgLocs; > CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); > - CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_32_C); > + if(CC==CallingConv::Fast && PerformTailCallOpt) > + CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_32_TailCall); > + else > + CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_32_C); > > // Get a count of how many bytes are to be pushed on the stack. > unsigned NumBytes = CCInfo.getNextStackOffset(); > + if (CC==CallingConv::Fast) > + NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG); > > Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, > getPointerTy())); > > @@ -1023,19 +1087,21 @@ > > if (InFlag.Val) > Ops.push_back(InFlag); > - > - Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, > - NodeTys, &Ops[0], Ops.size()); > + > + Chain = DAG.getNode(X86ISD::CALL, NodeTys, &Ops[0], Ops.size()); > InFlag = Chain.getValue(1); > > // Create the CALLSEQ_END node. > unsigned NumBytesForCalleeToPush = 0; > > - if (CC == CallingConv::X86_StdCall) { > + if (CC == CallingConv::X86_StdCall || > + (CC == CallingConv::Fast && PerformTailCallOpt)) { > if (isVarArg) > NumBytesForCalleeToPush = isSRet ? 4 : 0; > else > NumBytesForCalleeToPush = NumBytes; > + assert(!(isVarArg && CC==CallingConv::Fast) && > + "CallingConv::Fast does not support varargs."); > } else { > // If this is is a call to a struct-return function, the callee > // pops the hidden struct pointer, so we have to push it back. > @@ -1132,7 +1198,8 @@ > > if (!Subtarget->isTargetCygMing() && !Subtarget- > >isTargetWindows()) { > // Make sure the instruction takes 8n+4 bytes to make sure the > start of the > - // arguments and the arguments after the retaddr has been > pushed are aligned. > + // arguments and the arguments after the retaddr has been > pushed are > + // aligned. > if ((StackSize & 7) == 0) > StackSize += 4; > } > @@ -1194,7 +1261,8 @@ > > if (!Subtarget->isTargetCygMing() && !Subtarget- > >isTargetWindows()) { > // Make sure the instruction takes 8n+4 bytes to make sure the > start of the > - // arguments and the arguments after the retaddr has been > pushed are aligned. > + // arguments and the arguments after the retaddr has been > pushed are > + // aligned. > if ((NumBytes & 7) == 0) > NumBytes += 4; > } > @@ -1292,8 +1360,8 @@ > if (InFlag.Val) > Ops.push_back(InFlag); > > - // FIXME: Do not generate X86ISD::TAILCALL for now. > - Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, > + assert(isTailCall==false && "no tail call here"); > + Chain = DAG.getNode(X86ISD::CALL, > NodeTys, &Ops[0], Ops.size()); > InFlag = Chain.getValue(1); > > @@ -1312,6 +1380,314 @@ > return SDOperand(LowerCallResult(Chain, InFlag, Op.Val, CC, DAG), > Op.ResNo); > } > > +// > = > = > = > ----------------------------------------------------------------------= > ==// > +// Fast Calling Convention (tail call) implementation > +// > = > = > = > ----------------------------------------------------------------------= > ==// > + > +// Like std call, callee cleans arguments, convention except that > ECX is > +// reserved for storing the tail called function address. Only 2 > registers are > +// free for argument passing (inreg). Tail call optimization is > performed > +// provided: > +// * tailcallopt is enabled > +// * caller/callee are fastcc > +// * elf/pic is disabled OR > +// * elf/pic enabled + callee is in module + callee > has > +// visibility protected or hidden > +// To ensure the stack is aligned according to platform abi pass > +// tail-call-align-stack. This makes sure that argument delta is > always > +// multiples of stack alignment. (Dynamic linkers need this - > darwin's dyld for > +// example) > +// If a tail called function callee has more arguments than the > caller the > +// caller needs to make sure that there is room to move the > RETADDR to. This is > +// achived by reserving an area the size of the argument delta > right after the > +// original REtADDR, but before the saved framepointer or the > spilled registers > +// e.g. caller(arg1, arg2) calls callee(arg1, arg2,arg3,arg4) > +// stack layout: > +// arg1 > +// arg2 > +// RETADDR > +// [ new RETADDR > +// move area ] > +// (possible EBP) > +// ESI > +// EDI > +// local1 .. > + > +/// GetAlignedArgumentStackSize - Make the stack size align e.g 16n > + 12 aligned > +/// for a 16 byte align requirement. > +unsigned X86TargetLowering::GetAlignedArgumentStackSize(unsigned > StackSize, > + > SelectionDAG& DAG) { > + if (PerformTailCallOpt) { > + MachineFunction &MF = DAG.getMachineFunction(); > + const TargetMachine &TM = MF.getTarget(); > + const TargetFrameInfo &TFI = *TM.getFrameInfo(); > + unsigned StackAlignment = TFI.getStackAlignment(); > + uint64_t AlignMask = StackAlignment - 1; > + int64_t Offset = StackSize; > + unsigned SlotSize = Subtarget->is64Bit() ? 8 : 4; > + if ( (Offset & AlignMask) <= (StackAlignment - SlotSize) ) { > + // Number smaller than 12 so just add the difference. > + Offset += ((StackAlignment - SlotSize) - (Offset & AlignMask)); > + } else { > + // Mask out lower bits, add stackalignment once plus the 12 > bytes. > + Offset = ((~AlignMask) & Offset) + StackAlignment + > + (StackAlignment-SlotSize); > + } > + StackSize = Offset; > + } > + return StackSize; > +} > + > +/// IsEligibleForTailCallElimination - Check to see whether the > next instruction > +// following the call is a return. A function is eligible if caller/ > callee > +// calling conventions match, currently only fastcc supports tail > calls, and the > +// function CALL is immediatly followed by a RET. > +bool X86TargetLowering::IsEligibleForTailCallOptimization(SDOperand > Call, > + SDOperand Ret, > + SelectionDAG& > DAG) const { > + bool IsEligible = false; > + > + // Check whether CALL node immediatly preceeds the RET node and > whether the > + // return uses the result of the node or is a void return. > + if ((Ret.getNumOperands() == 1 && > + (Ret.getOperand(0)== SDOperand(Call.Val,1) || > + Ret.getOperand(0)== SDOperand(Call.Val,0))) || > + (Ret.getOperand(0)== SDOperand(Call.Val,Call.Val- > >getNumValues()-1) && > + Ret.getOperand(1)== SDOperand(Call.Val,0))) { > + MachineFunction &MF = DAG.getMachineFunction(); > + unsigned CallerCC = MF.getFunction()->getCallingConv(); > + unsigned CalleeCC = cast(Call.getOperand(1))- > >getValue(); > + if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) { > + SDOperand Callee = Call.getOperand(4); > + // On elf/pic %ebx needs to be livein. > + if(getTargetMachine().getRelocationModel() == Reloc::PIC_ && > + Subtarget->isPICStyleGOT()) { > + // Can only do local tail calls with PIC. > + GlobalValue * GV = 0; > + GlobalAddressSDNode *G = > dyn_cast(Callee); > + if(G != 0 && > + (GV = G->getGlobal()) && > + (GV->hasHiddenVisibility() || GV- > >hasProtectedVisibility())) > + IsEligible=true; > + } else { > + IsEligible=true; > + } > + } > + } > + return IsEligible; > +} > + > +SDOperand X86TargetLowering::LowerX86_TailCallTo(SDOperand Op, > + SelectionDAG > &DAG, > + unsigned CC) { > + SDOperand Chain = Op.getOperand(0); > + bool isVarArg = cast(Op.getOperand(2))- > >getValue() != 0; > + bool isTailCall = cast(Op.getOperand(3))- > >getValue() != 0; > + SDOperand Callee = Op.getOperand(4); > + bool is64Bit = Subtarget->is64Bit(); > + > + assert(isTailCall && PerformTailCallOpt && "Should only emit tail > calls."); > + > + // Analyze operands of the call, assigning locations to each > operand. > + SmallVector ArgLocs; > + CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); > + if (is64Bit) > + CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_64_TailCall); > + else > + CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_32_TailCall); > + > + > + // Lower arguments at fp - stackoffset + fpdiff. > + MachineFunction &MF = DAG.getMachineFunction(); > + > + unsigned NumBytesToBePushed = > + GetAlignedArgumentStackSize(CCInfo.getNextStackOffset(), DAG); > + > + unsigned NumBytesCallerPushed = > + MF.getInfo()->getBytesToPopOnReturn(); > + int FPDiff = NumBytesCallerPushed - NumBytesToBePushed; > + > + // Set the delta of movement of the returnaddr stackslot. > + // But only set if delta is greater than previous delta. > + if (FPDiff < (MF.getInfo()- > >getTCReturnAddrDelta())) > + MF.getInfo()- > >setTCReturnAddrDelta(FPDiff); > + > + // Adjust the ret address stack slot. > + if (FPDiff) { > + MVT::ValueType VT = is64Bit ? MVT::i64 : MVT::i32; > + SDOperand RetAddrFrIdx = getReturnAddressFrameIndex(DAG); > + RetAddrFrIdx = > + DAG.getLoad(VT, DAG.getEntryNode(),RetAddrFrIdx, NULL, 0); > + // Emit a store of the saved ret value to the new location. > + int SlotSize = is64Bit ? 8 : 4; > + int NewReturnAddrFI = > + MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff- > SlotSize); > + SDOperand NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, > VT); > + Chain = DAG.getStore(Chain,RetAddrFrIdx, NewRetAddrFrIdx, NULL, > 0); > + } > + > + Chain = DAG. > + getCALLSEQ_START(Chain, DAG.getConstant(NumBytesToBePushed, > getPointerTy())); > + > + SmallVector, 8> RegsToPass; > + SmallVector MemOpChains; > + SmallVector MemOpChains2; > + SDOperand FramePtr, StackPtr; > + SDOperand PtrOff; > + SDOperand FIN; > + int FI = 0; > + > + // Walk the register/memloc assignments, inserting copies/loads. > Lower > + // arguments first to the stack slot where they would normally - > in case of a > + // normal function call - be. > + for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { > + CCValAssign &VA = ArgLocs[i]; > + SDOperand Arg = Op.getOperand(5+2*VA.getValNo()); > + > + // Promote the value if needed. > + switch (VA.getLocInfo()) { > + default: assert(0 && "Unknown loc info!"); > + case CCValAssign::Full: break; > + case CCValAssign::SExt: > + Arg = DAG.getNode(ISD::SIGN_EXTEND, VA.getLocVT(), Arg); > + break; > + case CCValAssign::ZExt: > + Arg = DAG.getNode(ISD::ZERO_EXTEND, VA.getLocVT(), Arg); > + break; > + case CCValAssign::AExt: > + Arg = DAG.getNode(ISD::ANY_EXTEND, VA.getLocVT(), Arg); > + break; > + } > + > + if (VA.isRegLoc()) { > + RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); > + } else { > + assert(VA.isMemLoc()); > + if (StackPtr.Val == 0) > + StackPtr = DAG.getRegister(getStackPtrReg(), getPointerTy()); > + > + MemOpChains.push_back(LowerMemOpCallTo(Op, DAG, StackPtr, VA, > Chain, > + Arg)); > + } > + } > + > + if (!MemOpChains.empty()) > + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, > + &MemOpChains[0], MemOpChains.size()); > + > + // Build a sequence of copy-to-reg nodes chained together with > token chain > + // and flag operands which copy the outgoing args into registers. > + SDOperand InFlag; > + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { > + Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, > RegsToPass[i].second, > + InFlag); > + InFlag = Chain.getValue(1); > + } > + InFlag = SDOperand(); > + // Copy from stack slots to stack slot of a tail called function. > This needs > + // to be done because if we would lower the arguments directly to > their real > + // stack slot we might end up overwriting each other. > + // TODO: To make this more efficient (sometimes saving a store/ > load) we could > + // analyse the arguments and emit this store/load/store sequence > only for > + // arguments which would be overwritten otherwise. > + for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { > + CCValAssign &VA = ArgLocs[i]; > + if (!VA.isRegLoc()) { > + SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo()); > + unsigned Flags = cast(FlagsOp)->getValue(); > + > + // Get source stack slot. > + SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), > getPointerTy()); > + PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, > PtrOff); > + // Create frame index. > + int32_t Offset = VA.getLocMemOffset()+FPDiff; > + uint32_t OpSize = (MVT::getSizeInBits(VA.getLocVT())+7)/8; > + FI = MF.getFrameInfo()->CreateFixedObject(OpSize, Offset); > + FIN = DAG.getFrameIndex(FI, MVT::i32); > + if (Flags & ISD::ParamFlags::ByVal) { > + // Copy relative to framepointer. > + unsigned Align = 1 << ((Flags & > ISD::ParamFlags::ByValAlign) >> > + ISD::ParamFlags::ByValAlignOffs); > + > + unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >> > + ISD::ParamFlags::ByValSizeOffs; > + > + SDOperand AlignNode = DAG.getConstant(Align, MVT::i32); > + SDOperand SizeNode = DAG.getConstant(Size, MVT::i32); > + // Copy relative to framepointer. > + MemOpChains2.push_back(DAG.getNode(ISD::MEMCPY, MVT::Other, > Chain, FIN, > + PtrOff, SizeNode, > AlignNode)); > + } else { > + SDOperand LoadedArg = DAG.getLoad(VA.getValVT(), Chain, > PtrOff, NULL,0); > + // Store relative to framepointer. > + MemOpChains2.push_back(DAG.getStore(Chain, LoadedArg, FIN, > NULL, 0)); > + } > + } > + } > + > + if (!MemOpChains2.empty()) > + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, > + &MemOpChains2[0], MemOpChains.size()); > + > + // ELF / PIC requires GOT in the EBX register before function > calls via PLT > + // GOT pointer. > + // Does not work with tail call since ebx is not restored > correctly by > + // tailcaller. TODO: at least for x86 - verify for x86-64 > + > + // If the callee is a GlobalAddress node (quite common, every > direct call is) > + // turn it into a TargetGlobalAddress node so that legalize > doesn't hack it. > + if (GlobalAddressSDNode *G = > dyn_cast(Callee)) { > + // We should use extra load for direct calls to dllimported > functions in > + // non-JIT mode. > + if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(), > + getTargetMachine(), true)) > + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), > getPointerTy()); > + } else if (ExternalSymbolSDNode *S = > dyn_cast(Callee)) > + Callee = DAG.getTargetExternalSymbol(S->getSymbol(), > getPointerTy()); > + else { > + assert(Callee.getOpcode() == ISD::LOAD && > + "Function destination must be loaded into virtual > register"); > + unsigned Opc = is64Bit ? X86::R9 : X86::ECX; > + > + Chain = DAG.getCopyToReg(Chain, > + DAG.getRegister(Opc, getPointerTy()) , > + Callee,InFlag); > + Callee = DAG.getRegister(Opc, getPointerTy()); > + // Add register as live out. > + DAG.getMachineFunction().addLiveOut(Opc); > + } > + > + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); > + SmallVector Ops; > + > + Ops.push_back(Chain); > + Ops.push_back(DAG.getConstant(NumBytesToBePushed, getPointerTy())); > + Ops.push_back(DAG.getConstant(0, getPointerTy())); > + if (InFlag.Val) > + Ops.push_back(InFlag); > + Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], > Ops.size()); > + InFlag = Chain.getValue(1); > + > + // Returns a chain & a flag for retval copy to use. > + NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); > + Ops.clear(); > + Ops.push_back(Chain); > + Ops.push_back(Callee); > + Ops.push_back(DAG.getConstant(FPDiff, MVT::i32)); > + // Add argument registers to the end of the list so that they are > known live > + // into the call. > + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) > + Ops.push_back(DAG.getRegister(RegsToPass[i].first, > + > RegsToPass[i].second.getValueType())); > + if (InFlag.Val) > + Ops.push_back(InFlag); > + assert(InFlag.Val && > + "Flag must be set. Depend on flag being set in LowerRET"); > + Chain = DAG.getNode(X86ISD::TAILCALL, > + Op.Val->getVTList(), &Ops[0], Ops.size()); > + > + return SDOperand(Chain.Val, Op.ResNo); > +} > > // > = > = > = > ----------------------------------------------------------------------= > ==// > // X86-64 C Calling Convention implementation > @@ -1323,6 +1699,7 @@ > MachineFrameInfo *MFI = MF.getFrameInfo(); > SDOperand Root = Op.getOperand(0); > bool isVarArg = cast(Op.getOperand(2))- > >getValue() != 0; > + unsigned CC= MF.getFunction()->getCallingConv(); > > static const unsigned GPR64ArgRegs[] = { > X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8, X86::R9 > @@ -1335,9 +1712,12 @@ > > // Assign locations to all of the incoming arguments. > SmallVector ArgLocs; > - CCState CCInfo(MF.getFunction()->getCallingConv(), isVarArg, > + CCState CCInfo(CC, isVarArg, > getTargetMachine(), ArgLocs); > - CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_64_C); > + if (CC == CallingConv::Fast && PerformTailCallOpt) > + CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_64_TailCall); > + else > + CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_64_C); > > SmallVector ArgValues; > unsigned LastVal = ~0U; > @@ -1398,10 +1778,14 @@ > } > > unsigned StackSize = CCInfo.getNextStackOffset(); > + if (CC==CallingConv::Fast) > + StackSize =GetAlignedArgumentStackSize(StackSize, DAG); > > // If the function takes variable number of arguments, make a > frame index for > // the start of the first vararg value... for expansion of > llvm.va_start. > if (isVarArg) { > + assert(CC!=CallingConv::Fast > + && "Var arg not supported with calling convention > fastcc"); > unsigned NumIntRegs = CCInfo.getFirstUnallocated(GPR64ArgRegs, 6); > unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs, 8); > > @@ -1446,10 +1830,14 @@ > } > > ArgValues.push_back(Root); > - > - BytesToPopOnReturn = 0; // Callee pops nothing. > - BytesCallerReserves = StackSize; > - > + // Tail call convention (fastcc) needs callee pop. > + if (CC == CallingConv::Fast && PerformTailCallOpt){ > + BytesToPopOnReturn = StackSize; // Callee pops everything. > + BytesCallerReserves = 0; > + } else { > + BytesToPopOnReturn = 0; // Callee pops nothing. > + BytesCallerReserves = StackSize; > + } > X86MachineFunctionInfo *FuncInfo = > MF.getInfo(); > FuncInfo->setBytesToPopOnReturn(BytesToPopOnReturn); > > @@ -1463,16 +1851,21 @@ > unsigned CC) { > SDOperand Chain = Op.getOperand(0); > bool isVarArg = cast(Op.getOperand(2))- > >getValue() != 0; > - bool isTailCall = cast(Op.getOperand(3))- > >getValue() != 0; > SDOperand Callee = Op.getOperand(4); > > // Analyze operands of the call, assigning locations to each > operand. > SmallVector ArgLocs; > CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); > - CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_64_C); > + if (CC==CallingConv::Fast) > + CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_64_TailCall); > + else > + CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_64_C); > > // Get a count of how many bytes are to be pushed on the stack. > unsigned NumBytes = CCInfo.getNextStackOffset(); > + if (CC == CallingConv::Fast) > + NumBytes = GetAlignedArgumentStackSize(NumBytes,DAG); > + > Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, > getPointerTy())); > > SmallVector, 8> RegsToPass; > @@ -1526,6 +1919,9 @@ > } > > if (isVarArg) { > + assert ( CallingConv::Fast != CC && > + "Var args not supported with calling convention > fastcc"); > + > // From AMD64 ABI document: > // For calls that may call functions that use varargs or stdargs > // (prototype-less calls or calls to functions containing > ellipsis (...) in > @@ -1574,17 +1970,22 @@ > if (InFlag.Val) > Ops.push_back(InFlag); > > - // FIXME: Do not generate X86ISD::TAILCALL for now. > - Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, > + Chain = DAG.getNode(X86ISD::CALL, > NodeTys, &Ops[0], Ops.size()); > InFlag = Chain.getValue(1); > - > + int NumBytesForCalleeToPush = 0; > + if (CC==CallingConv::Fast) { > + NumBytesForCalleeToPush = NumBytes; // Callee pops everything > + > + } else { > + NumBytesForCalleeToPush = 0; // Callee pops nothing. > + } > // Returns a flag for retval copy to use. > NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); > Ops.clear(); > Ops.push_back(Chain); > Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); > - Ops.push_back(DAG.getConstant(0, getPointerTy())); > + Ops.push_back(DAG.getConstant(NumBytesForCalleeToPush, > getPointerTy())); > Ops.push_back(InFlag); > Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size()); > InFlag = Chain.getValue(1); > @@ -3106,10 +3507,14 @@ > // SHUFPS the element to the lowest double word, then movss. > MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4); > SmallVector IdxVec; > - IdxVec.push_back(DAG.getConstant(Idx, > MVT::getVectorElementType(MaskVT))); > - IdxVec.push_back(DAG.getNode(ISD::UNDEF, > MVT::getVectorElementType(MaskVT))); > - IdxVec.push_back(DAG.getNode(ISD::UNDEF, > MVT::getVectorElementType(MaskVT))); > - IdxVec.push_back(DAG.getNode(ISD::UNDEF, > MVT::getVectorElementType(MaskVT))); > + IdxVec. > + push_back(DAG.getConstant(Idx, > MVT::getVectorElementType(MaskVT))); > + IdxVec. > + push_back(DAG.getNode(ISD::UNDEF, > MVT::getVectorElementType(MaskVT))); > + IdxVec. > + push_back(DAG.getNode(ISD::UNDEF, > MVT::getVectorElementType(MaskVT))); > + IdxVec. > + push_back(DAG.getNode(ISD::UNDEF, > MVT::getVectorElementType(MaskVT))); > SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, > &IdxVec[0], IdxVec.size()); > Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(), > @@ -3128,7 +3533,8 @@ > MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4); > SmallVector IdxVec; > IdxVec.push_back(DAG.getConstant(1, > MVT::getVectorElementType(MaskVT))); > - IdxVec.push_back(DAG.getNode(ISD::UNDEF, > MVT::getVectorElementType(MaskVT))); > + IdxVec. > + push_back(DAG.getNode(ISD::UNDEF, > MVT::getVectorElementType(MaskVT))); > SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, > &IdxVec[0], IdxVec.size()); > Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(), > @@ -3777,17 +4183,23 @@ > } > > SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG > &DAG) { > - unsigned CallingConv= cast(Op.getOperand(1))- > >getValue(); > + unsigned CallingConv = cast(Op.getOperand(1))- > >getValue(); > + bool isTailCall = cast(Op.getOperand(3))- > >getValue() != 0; > > - if (Subtarget->is64Bit()) > - return LowerX86_64CCCCallTo(Op, DAG, CallingConv); > + if (Subtarget->is64Bit()) > + if(CallingConv==CallingConv::Fast && isTailCall && > PerformTailCallOpt) > + return LowerX86_TailCallTo(Op, DAG, CallingConv); > + else > + return LowerX86_64CCCCallTo(Op, DAG, CallingConv); > else > switch (CallingConv) { > default: > assert(0 && "Unsupported calling convention"); > case CallingConv::Fast: > - // TODO: Implement fastcc > - // Falls through > + if (isTailCall && PerformTailCallOpt) > + return LowerX86_TailCallTo(Op, DAG, CallingConv); > + else > + return LowerCCCCallTo(Op,DAG, CallingConv); > case CallingConv::C: > case CallingConv::X86_StdCall: > return LowerCCCCallTo(Op, DAG, CallingConv); > @@ -3855,8 +4267,7 @@ > default: > assert(0 && "Unsupported calling convention"); > case CallingConv::Fast: > - // TODO: implement fastcc. > - > + return LowerCCCArguments(Op,DAG, true); > // Falls through > case CallingConv::C: > return LowerCCCArguments(Op, DAG); > @@ -4176,7 +4587,8 @@ > SDOperand TheOp = Op.getOperand(0); > SDOperand rd = DAG.getNode(X86ISD::RDTSC_DAG, Tys, &TheOp, 1); > if (Subtarget->is64Bit()) { > - SDOperand Copy1 = DAG.getCopyFromReg(rd, X86::RAX, MVT::i64, > rd.getValue(1)); > + SDOperand Copy1 = > + DAG.getCopyFromReg(rd, X86::RAX, MVT::i64, rd.getValue(1)); > SDOperand Copy2 = DAG.getCopyFromReg(Copy1.getValue(1), X86::RDX, > MVT::i64, Copy1.getValue(2)); > SDOperand Tmp = DAG.getNode(ISD::SHL, MVT::i64, Copy2, > @@ -4612,6 +5024,7 @@ > case X86ISD::TLSADDR: return "X86ISD::TLSADDR"; > case X86ISD::THREAD_POINTER: return "X86ISD::THREAD_POINTER"; > case X86ISD::EH_RETURN: return "X86ISD::EH_RETURN"; > + case X86ISD::TC_RETURN: return "X86ISD::TC_RETURN"; > } > } > > @@ -4885,7 +5298,7 @@ > i %= NumElems; > if (V.getOpcode() == ISD::SCALAR_TO_VECTOR) { > return (i == 0) > - ? V.getOperand(0) : DAG.getNode(ISD::UNDEF, > MVT::getVectorElementType(VT)); > + ? V.getOperand(0) : DAG.getNode(ISD::UNDEF, > MVT::getVectorElementType(VT)); > } else if (V.getOpcode() == ISD::VECTOR_SHUFFLE) { > SDOperand Idx = PermMask.getOperand(i); > if (Idx.getOpcode() == ISD::UNDEF) > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=42870&r1=42869&r2=42870&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Thu Oct 11 14:40:01 > 2007 > @@ -181,7 +181,14 @@ > TLSADDR, THREAD_POINTER, > > // Exception Handling helpers > - EH_RETURN > + EH_RETURN, > + > + // tail call return > + // oeprand #0 chain > + // operand #1 callee (register or absolute) > + // operand #2 stack adjustment > + // operand #3 optional in flag > + TC_RETURN > }; > } > > @@ -285,6 +292,7 @@ > unsigned VarArgsFPOffset; // X86-64 vararg func fp reg > offset. > int BytesToPopOnReturn; // Number of arg bytes ret > should pop. > int BytesCallerReserves; // Number of arg bytes caller > makes. > + > public: > explicit X86TargetLowering(TargetMachine &TM); > > @@ -364,6 +372,14 @@ > virtual bool isVectorClearMaskLegal(std::vector &BVOps, > MVT::ValueType EVT, > SelectionDAG &DAG) const; > + > + /// IsEligibleForTailCallOptimization - Check whether the call > is eligible > + /// for tail call optimization. Target which want to do tail call > + /// optimization should implement this function. > + virtual bool IsEligibleForTailCallOptimization(SDOperand Call, > + SDOperand Ret, > + SelectionDAG > &DAG) const; > + > private: > /// Subtarget - Keep a pointer to the X86Subtarget around so > that we can > /// make the right decision when generating code for different > targets. > @@ -372,7 +388,7 @@ > > /// X86StackPtr - X86 physical register used as stack ptr. > unsigned X86StackPtr; > - > + > /// X86ScalarSSEf32, X86ScalarSSEf64 - Select between SSE or x87 > /// floating point ops. > /// When SSE is available, use it for f32 operations. > @@ -402,6 +418,10 @@ > SDOperand LowerX86_64CCCArguments(SDOperand Op, SelectionDAG > &DAG); > SDOperand LowerX86_64CCCCallTo(SDOperand Op, SelectionDAG > &DAG,unsigned CC); > > + // fast calling convention (tail call) implementation for > 32/64bit > + SDOperand LowerX86_TailCallTo(SDOperand Op, > + SelectionDAG & DAG, unsigned > CC); > + unsigned GetAlignedArgumentStackSize(unsigned StackSize, > SelectionDAG &DAG); > // Fast and FastCall Calling Convention implementation. > SDOperand LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG); > SDOperand LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG, > unsigned CC); > > Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=42870&r1=42869&r2=42870&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Thu Oct 11 14:40:01 > 2007 > @@ -706,6 +706,8 @@ > if (MBB.empty()) return false; > > switch (MBB.back().getOpcode()) { > + case X86::TCRETURNri: > + case X86::TCRETURNdi: > case X86::RET: // Return. > case X86::RETI: > case X86::TAILJMPd: > > Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=42870&r1=42869&r2=42870&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) > +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Oct 11 14:40:01 2007 > @@ -55,6 +55,8 @@ > > def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>; > > +def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, > i32>]>; > + > def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>; > def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>; > > @@ -73,7 +75,7 @@ > [SDNPHasChain, SDNPOutFlag]>; > def X86callseq_end : > SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd, > - [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; > + [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; > > def X86call : SDNode<"X86ISD::CALL", SDT_X86Call, > [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>; > @@ -99,6 +101,8 @@ > def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET, > [SDNPHasChain]>; > > +def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET, > + [SDNPHasChain, SDNPOptInFlag]>; > > // > = > = > = > ----------------------------------------------------------------------= > ==// > // X86 Operand Definitions. > @@ -356,15 +360,30 @@ > } > > // Tail call stuff. > + > +def TAILCALL : I<0, Pseudo, (outs), (ins ), > + "#TAILCALL", > + []>; > + > +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in > +def TCRETURNdi : I<0, Pseudo, (outs), (ins i32imm:$dst, i32imm: > $offset), > + "#TC_RETURN $dst $offset", > + []>; > + > let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in > - def TAILJMPd : IBr<0xE9, (ins i32imm:$dst), "jmp\t${dst:call} # > TAIL CALL", > +def TCRETURNri : I<0, Pseudo, (outs), (ins GR32:$dst, i32imm: > $offset), > + "#TC_RETURN $dst $offset", > []>; > + > let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in > - def TAILJMPr : I<0xFF, MRM4r, (outs), (ins GR32:$dst), "jmp\t{*} > $dst # TAIL CALL", > + def TAILJMPd : IBr<0xE9, (ins i32imm:$dst), "jmp\t${dst:call} # > TAILCALL", > []>; > let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in > + def TAILJMPr : I<0xFF, MRM4r, (outs), (ins GR32:$dst), "jmp{l} > \t{*}$dst # TAILCALL", > + []>; > +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in > def TAILJMPm : I<0xFF, MRM4m, (outs), (ins i32mem:$dst), > - "jmp\t{*}$dst # TAIL CALL", []>; > + "jmp\t{*}$dst # TAILCALL", []>; > > // > = > = > = > ----------------------------------------------------------------------= > ==// > // Miscellaneous Instructions... > @@ -2507,13 +2526,23 @@ > (MOV32mi addr:$dst, texternalsym:$src)>; > > // Calls > +// tailcall stuff > def : Pat<(X86tailcall GR32:$dst), > - (CALL32r GR32:$dst)>; > + (TAILCALL)>; > > def : Pat<(X86tailcall (i32 tglobaladdr:$dst)), > - (CALLpcrel32 tglobaladdr:$dst)>; > + (TAILCALL)>; > def : Pat<(X86tailcall (i32 texternalsym:$dst)), > - (CALLpcrel32 texternalsym:$dst)>; > + (TAILCALL)>; > + > +def : Pat<(X86tcret GR32:$dst, imm:$off), > + (TCRETURNri GR32:$dst, imm:$off)>; > + > +def : Pat<(X86tcret (i32 tglobaladdr:$dst), imm:$off), > + (TCRETURNdi texternalsym:$dst, imm:$off)>; > + > +def : Pat<(X86tcret (i32 texternalsym:$dst), imm:$off), > + (TCRETURNdi texternalsym:$dst, imm:$off)>; > > def : Pat<(X86call (i32 tglobaladdr:$dst)), > (CALLpcrel32 tglobaladdr:$dst)>; > > Modified: llvm/trunk/lib/Target/X86/X86InstrX86-64.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrX86-64.td?rev=42870&r1=42869&r2=42870&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrX86-64.td (original) > +++ llvm/trunk/lib/Target/X86/X86InstrX86-64.td Thu Oct 11 14:40:01 > 2007 > @@ -102,6 +102,23 @@ > "call\t{*}$dst", []>; > } > > + > + > +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in > +def TCRETURNdi64 : I<0, Pseudo, (outs), (ins i64imm:$dst, i32imm: > $offset), > + "#TC_RETURN $dst $offset", > + []>; > + > +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in > +def TCRETURNri64 : I<0, Pseudo, (outs), (ins GR64:$dst, i32imm: > $offset), > + "#TC_RETURN $dst $offset", > + []>; > + > + > +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in > + def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q} > \t{*}$dst # TAILCALL", > + []>; > + > // Branches > let isBranch = 1, isTerminator = 1, isBarrier = 1 in { > def JMP64r : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q} > \t{*}$dst", > @@ -1105,6 +1122,24 @@ > def : Pat<(X86tailcall GR64:$dst), > (CALL64r GR64:$dst)>; > > + > +// tailcall stuff > +def : Pat<(X86tailcall GR32:$dst), > + (TAILCALL)>; > +def : Pat<(X86tailcall (i64 tglobaladdr:$dst)), > + (TAILCALL)>; > +def : Pat<(X86tailcall (i64 texternalsym:$dst)), > + (TAILCALL)>; > + > +def : Pat<(X86tcret GR64:$dst, imm:$off), > + (TCRETURNri64 GR64:$dst, imm:$off)>; > + > +def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off), > + (TCRETURNdi64 texternalsym:$dst, imm:$off)>; > + > +def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off), > + (TCRETURNdi64 texternalsym:$dst, imm:$off)>; > + > // Comparisons. > > // TEST R,R is smaller than CMP R,0 > > Modified: llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h?rev=42870&r1=42869&r2=42870&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h (original) > +++ llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h Thu Oct 11 > 14:40:01 2007 > @@ -47,18 +47,26 @@ > > // FrameIndex for return slot. > int ReturnAddrIndex; > + > + // Delta the ReturnAddr stack slot is moved > + // Used for creating an area before the register spill area on > the stack > + // the returnaddr can be savely move to this area > + int TailCallReturnAddrDelta; > + > public: > X86MachineFunctionInfo() : ForceFramePointer(false), > CalleeSavedFrameSize(0), > BytesToPopOnReturn(0), > DecorationStyle(None), > - ReturnAddrIndex(0) {} > + ReturnAddrIndex(0), > + TailCallReturnAddrDelta(0){} > > X86MachineFunctionInfo(MachineFunction &MF) : > ForceFramePointer(false), > > CalleeSavedFrameSize(0), > BytesToPopOnReturn(0), > DecorationStyle(None), > - ReturnAddrIndex(0) {} > + ReturnAddrIndex(0), > + > TailCallReturnAddrDelta(0) {} > > bool getForceFramePointer() const { return ForceFramePointer;} > void setForceFramePointer(bool forceFP) { ForceFramePointer = > forceFP; } > @@ -74,6 +82,9 @@ > > int getRAIndex() const { return ReturnAddrIndex; } > void setRAIndex(int Index) { ReturnAddrIndex = Index; } > + > + int getTCReturnAddrDelta() const { return > TailCallReturnAddrDelta; } > + void setTCReturnAddrDelta(int delta) {TailCallReturnAddrDelta = > delta;} > }; > } // End llvm namespace > > > Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=42870&r1=42869&r2=42870&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Thu Oct 11 > 14:40:01 2007 > @@ -1436,18 +1436,42 @@ > > if (!hasFP(MF)) > Offset += MF.getFrameInfo()->getStackSize(); > - else > + else { > Offset += SlotSize; // Skip the saved EBP > - > + // Skip the RETADDR move area > + X86MachineFunctionInfo *X86FI = > MF.getInfo(); > + int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); > + if (TailCallReturnAddrDelta < 0) Offset -= > TailCallReturnAddrDelta; > + } > + > MI.getOperand(i+3).ChangeToImmediate(Offset); > } > > void > X86RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction > &MF) const{ > + X86MachineFunctionInfo *X86FI = > MF.getInfo(); > + int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); > + if (TailCallReturnAddrDelta < 0) { > + // create RETURNADDR area > + // arg > + // arg > + // RETADDR > + // { ... > + // RETADDR area > + // ... > + // } > + // [EBP] > + MF.getFrameInfo()-> > + CreateFixedObject(-TailCallReturnAddrDelta, > + (-1*SlotSize)+TailCallReturnAddrDelta); > + } > if (hasFP(MF)) { > + assert((TailCallReturnAddrDelta <= 0) && > + "The Delta should always be zero or negative"); > // Create a frame entry for the EBP register that must be saved. > int FrameIdx = MF.getFrameInfo()->CreateFixedObject(SlotSize, > - > (int)SlotSize * -2); > + > (int)SlotSize * -2+ > + > TailCallReturnAddrDelta); > assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() && > "Slot for EBP register must be last in order to be > found!"); > } > @@ -1530,6 +1554,41 @@ > } > } > > +/// mergeSPUpdates - Checks the instruction before/after the passed > +/// instruction. If it is an ADD/SUB instruction it is deleted > +/// argument and the stack adjustment is returned as a positive > value for ADD > +/// and a negative for SUB. > +static int mergeSPUpdates(MachineBasicBlock &MBB, > + MachineBasicBlock::iterator &MBBI, > + unsigned StackPtr, > + bool doMergeWithPrevious) { > + > + if ((doMergeWithPrevious && MBBI == MBB.begin()) || > + (!doMergeWithPrevious && MBBI == MBB.end())) > + return 0; > + > + int Offset = 0; > + > + MachineBasicBlock::iterator PI = doMergeWithPrevious ? > prior(MBBI) : MBBI; > + MachineBasicBlock::iterator NI = doMergeWithPrevious ? 0 : > next(MBBI); > + unsigned Opc = PI->getOpcode(); > + if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || > + Opc == X86::ADD32ri || Opc == X86::ADD32ri8) && > + PI->getOperand(0).getReg() == StackPtr){ > + Offset += PI->getOperand(2).getImm(); > + MBB.erase(PI); > + if (!doMergeWithPrevious) MBBI = NI; > + } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || > + Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && > + PI->getOperand(0).getReg() == StackPtr) { > + Offset -= PI->getOperand(2).getImm(); > + MBB.erase(PI); > + if (!doMergeWithPrevious) MBBI = NI; > + } > + > + return Offset; > +} > + > void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { > MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB > MachineFrameInfo *MFI = MF.getFrameInfo(); > @@ -1543,10 +1602,23 @@ > // Prepare for frame info. > unsigned FrameLabelId = 0; > > - // Get the number of bytes to allocate from the FrameInfo > + // Get the number of bytes to allocate from the FrameInfo. > uint64_t StackSize = MFI->getStackSize(); > + // Add RETADDR move area to callee saved frame size. > + int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); > + if (TailCallReturnAddrDelta < 0) > + X86FI->setCalleeSavedFrameSize( > + X86FI->getCalleeSavedFrameSize() +(- > TailCallReturnAddrDelta)); > uint64_t NumBytes = StackSize - X86FI->getCalleeSavedFrameSize(); > > + // Insert stack pointer adjustment for later moving of return > addr. Only > + // applies to tail call optimized functions where the callee > argument stack > + // size is bigger than the callers. > + if (TailCallReturnAddrDelta < 0) { > + BuildMI(MBB, MBBI, TII.get(Is64Bit? X86::SUB64ri32 : > X86::SUB32ri), > + StackPtr).addReg(StackPtr).addImm(- > TailCallReturnAddrDelta); > + } > + > if (hasFP(MF)) { > // Get the offset of the stack slot for the EBP register... > which is > // guaranteed to be the last slot by > processFunctionBeforeFrameFinalized. > @@ -1615,6 +1687,10 @@ > MBB.insert(MBBI, MI); > } > } else { > + // If there is an SUB32ri of ESP immediately before this > instruction, > + // merge the two. This can be the case when tail call > elimination is > + // enabled and the callee has more arguments then the caller. > + NumBytes -= mergeSPUpdates(MBB, MBBI, StackPtr, true); > // If there is an ADD32ri or SUB32ri of ESP immediately after > this > // instruction, merge the two instructions. > mergeSPUpdatesDown(MBB, MBBI, StackPtr, &NumBytes); > @@ -1711,6 +1787,10 @@ > switch (RetOpcode) { > case X86::RET: > case X86::RETI: > + case X86::TCRETURNdi: > + case X86::TCRETURNri: > + case X86::TCRETURNri64: > + case X86::TCRETURNdi64: > case X86::EH_RETURN: > case X86::TAILJMPd: > case X86::TAILJMPr: > @@ -1773,7 +1853,46 @@ > MachineOperand &DestAddr = MBBI->getOperand(0); > assert(DestAddr.isRegister() && "Offset should be in register!"); > BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::MOV64rr : > X86::MOV32rr),StackPtr). > - addReg(DestAddr.getReg()); > + addReg(DestAddr.getReg()); > + // Tail call return: adjust the stack pointer and jump to callee > + } else if (RetOpcode == X86::TCRETURNri || RetOpcode == > X86::TCRETURNdi || > + RetOpcode== X86::TCRETURNri64 || RetOpcode == > X86::TCRETURNdi64) { > + MBBI = prior(MBB.end()); > + MachineOperand &JumpTarget = MBBI->getOperand(0); > + MachineOperand &StackAdjust = MBBI->getOperand(1); > + assert( StackAdjust.isImmediate() && "Expecting immediate > value."); > + > + // Adjust stack pointer. > + int StackAdj = StackAdjust.getImm(); > + int MaxTCDelta = X86FI->getTCReturnAddrDelta(); > + int Offset = 0; > + assert(MaxTCDelta <= 0 && "MaxTCDelta should never be positive"); > + // Incoporate the retaddr area. > + Offset = StackAdj-MaxTCDelta; > + assert(Offset >= 0 && "Offset should never be negative"); > + if (Offset) { > + // Check for possible merge with preceeding ADD instruction. > + Offset += mergeSPUpdates(MBB, MBBI, StackPtr, true); > + emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, TII); > + } > + // Jump to label or value in register. > + if (RetOpcode == X86::TCRETURNdi|| RetOpcode == > X86::TCRETURNdi64) > + BuildMI(MBB, MBBI, TII.get(X86::TAILJMPd)). > + addGlobalAddress(JumpTarget.getGlobal(), > JumpTarget.getOffset()); > + else if (RetOpcode== X86::TCRETURNri64) { > + BuildMI(MBB, MBBI, TII.get(X86::TAILJMPr64), > JumpTarget.getReg()); > + } else > + BuildMI(MBB, MBBI, TII.get(X86::TAILJMPr), > JumpTarget.getReg()); > + // Delete the pseudo instruction TCRETURN. > + MBB.erase(MBBI); > + } else if ((RetOpcode == X86::RET || RetOpcode == X86::RETI) && > + (X86FI->getTCReturnAddrDelta() < 0)) { > + // Add the return addr area delta back since we are not tail > calling. > + int delta = -1*X86FI->getTCReturnAddrDelta(); > + MBBI = prior(MBB.end()); > + // Check for possible merge with preceeding ADD instruction. > + delta += mergeSPUpdates(MBB, MBBI, StackPtr, true); > + emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, TII); > } > } > > > Added: llvm/trunk/test/CodeGen/X86/tailcall1.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcall1.ll?rev=42870&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/tailcall1.ll (added) > +++ llvm/trunk/test/CodeGen/X86/tailcall1.ll Thu Oct 11 14:40:01 2007 > @@ -0,0 +1,11 @@ > +; RUN: llvm-as < %s | llc -tailcallopt | grep TAILCALL > +define fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4) { > +entry: > + ret i32 %a3 > +} > + > +define fastcc i32 @tailcaller(i32 %in1, i32 %in2) { > +entry: > + %tmp11 = tail call fastcc i32 @tailcallee( i32 %in1, i32 %in2, i32 > %in1, i32 %in2 ) ; [#uses=1] > + ret i32 %tmp11 > +} > > Added: llvm/trunk/test/CodeGen/X86/tailcallpic1.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcallpic1.ll?rev=42870&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/tailcallpic1.ll (added) > +++ llvm/trunk/test/CodeGen/X86/tailcallpic1.ll Thu Oct 11 14:40:01 > 2007 > @@ -0,0 +1,12 @@ > +; RUN: llvm-as < %s | llc -tailcallopt -mtriple=i686-pc-linux-gnu - > relocation-model=pic | grep TAILCALL > + > +define protected fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, > i32 %a4) { > +entry: > + ret i32 %a3 > +} > + > +define fastcc i32 @tailcaller(i32 %in1, i32 %in2) { > +entry: > + %tmp11 = tail call fastcc i32 @tailcallee( i32 %in1, i32 %in2, i32 > %in1, i32 %in2 ) ; [#uses=1] > + ret i32 %tmp11 > +} > > Added: llvm/trunk/test/CodeGen/X86/tailcallpic2.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcallpic2.ll?rev=42870&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/tailcallpic2.ll (added) > +++ llvm/trunk/test/CodeGen/X86/tailcallpic2.ll Thu Oct 11 14:40:01 > 2007 > @@ -0,0 +1,12 @@ > +; RUN: llvm-as < %s | llc -tailcallopt -mtriple=i686-pc-linux-gnu - > relocation-model=pic | grep -v TAILCALL > + > +define fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4) { > +entry: > + ret i32 %a3 > +} > + > +define fastcc i32 @tailcaller(i32 %in1, i32 %in2) { > +entry: > + %tmp11 = tail call fastcc i32 @tailcallee( i32 %in1, i32 %in2, i32 > %in1, i32 %in2 ) ; [#uses=1] > + ret i32 %tmp11 > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Thu Oct 11 20:30:29 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 Oct 2007 18:30:29 -0700 Subject: [llvm-commits] RFC: internal label names In-Reply-To: <041FE40B-A167-4A4B-A5C2-A25930B8E7BC@apple.com> References: <20071010194118.GT21991@village.us.cray.com> <041FE40B-A167-4A4B-A5C2-A25930B8E7BC@apple.com> Message-ID: On Oct 10, 2007, at 4:46 PM, Chris Lattner wrote: > > On Oct 10, 2007, at 12:41 PM, Dan Gohman wrote: > >>> 1. if the name is short, print it as you propose. >>> 2. if the name is long, print it with a number and optionally with a >>> subset of the name (last 10 chars?) >>> >>> This could be implemented by just adding a new ivar like >>> CurrentFunctionName that holds this. >> >> I think that is over complex :). C++ mangled names are ok with me >> here, >> but if they're unpleasant for others that's fine. > > Ok, if you can convince Evan, I'm fine with it "ready: fight!" Making me out to be a bad guy when in reality Chris is the picky one. :-) How about you check it in? I will ask it to be backed out if the long labels bug me. Evan > > > ;-) > > -Chris > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Thu Oct 11 20:37:10 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 12 Oct 2007 01:37:10 -0000 Subject: [llvm-commits] [llvm] r42888 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200710120137.l9C1bBB5015476@zion.cs.uiuc.edu> Author: johannes Date: Thu Oct 11 20:37:08 2007 New Revision: 42888 URL: http://llvm.org/viewvc/llvm-project?rev=42888&view=rev Log: PPC long double. Implement a couple more conversions. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=42888&r1=42887&r2=42888&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Oct 11 20:37:08 2007 @@ -5952,6 +5952,17 @@ Node, false, Hi); break; case ISD::FP_EXTEND: + if (VT == MVT::ppcf128) { + assert(Node->getOperand(0).getValueType()==MVT::f32 || + Node->getOperand(0).getValueType()==MVT::f64); + const uint64_t zero = 0; + if (Node->getOperand(0).getValueType()==MVT::f32) + Hi = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Node->getOperand(0)); + else + Hi = Node->getOperand(0); + Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &zero)), MVT::f64); + break; + } Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::FPEXT_F32_F64), Node, true,Hi); break; case ISD::FP_ROUND: @@ -6021,6 +6032,30 @@ case ISD::UINT_TO_FP: { bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP; MVT::ValueType SrcVT = Node->getOperand(0).getValueType(); + if (VT == MVT::ppcf128) { + static uint64_t zero = 0; + if (isSigned) { + Hi = LegalizeOp(DAG.getNode(ISD::SINT_TO_FP, MVT::f64, + Node->getOperand(0))); + Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &zero)), MVT::f64); + } else { + static uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 }; + Hi = LegalizeOp(DAG.getNode(ISD::SINT_TO_FP, MVT::f64, + Node->getOperand(0))); + Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &zero)), MVT::f64); + Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi); + ExpandOp(DAG.getNode(ISD::SELECT_CC, MVT::ppcf128, Node->getOperand(0), + DAG.getConstant(0, MVT::i32), + DAG.getNode(ISD::FADD, MVT::ppcf128, Hi, + DAG.getConstantFP( + APFloat(APInt(128, 2, TwoE32)), + MVT::ppcf128)), + Hi, + DAG.getCondCode(ISD::SETLT)), + Lo, Hi); + } + break; + } RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; if (Node->getOperand(0).getValueType() == MVT::i64) { if (VT == MVT::f32) From sabre at nondot.org Thu Oct 11 22:49:00 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 12 Oct 2007 03:49:00 -0000 Subject: [llvm-commits] [llvm] r42889 - /llvm/trunk/include/llvm/ADT/BitVector.h Message-ID: <200710120349.l9C3n0RU020934@zion.cs.uiuc.edu> Author: lattner Date: Thu Oct 11 22:48:59 2007 New Revision: 42889 URL: http://llvm.org/viewvc/llvm-project?rev=42889&view=rev Log: make operator== work with non-equal sized bitvectors, as long as the extra bits are all zeros. This allows "010" and "010000" to be treated as equal. Modified: llvm/trunk/include/llvm/ADT/BitVector.h Modified: llvm/trunk/include/llvm/ADT/BitVector.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/BitVector.h?rev=42889&r1=42888&r2=42889&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/BitVector.h (original) +++ llvm/trunk/include/llvm/ADT/BitVector.h Thu Oct 11 22:48:59 2007 @@ -259,12 +259,23 @@ // Comparison operators. bool operator==(const BitVector &RHS) const { - if (Size != RHS.Size) - return false; - - for (unsigned i = 0; i < NumBitWords(size()); ++i) + unsigned ThisWords = NumBitWords(size()); + unsigned RHSWords = NumBitWords(RHS.size()); + unsigned i; + for (i = 0; i != std::min(ThisWords, RHSWords); ++i) if (Bits[i] != RHS.Bits[i]) return false; + + // Verify that any extra words are all zeros. + if (i != ThisWords) { + for (; i != ThisWords; ++i) + if (Bits[i]) + return false; + } else if (i != RHSWords) { + for (; i != RHSWords; ++i) + if (RHS.Bits[i]) + return false; + } return true; } From sabre at nondot.org Fri Oct 12 00:29:53 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 12 Oct 2007 05:29:53 -0000 Subject: [llvm-commits] [llvm] r42890 - /llvm/trunk/test/Transforms/InstCombine/malloc3.ll Message-ID: <200710120529.l9C5Trqn024589@zion.cs.uiuc.edu> Author: lattner Date: Fri Oct 12 00:29:53 2007 New Revision: 42890 URL: http://llvm.org/viewvc/llvm-project?rev=42890&view=rev Log: testcase for PR1728 Added: llvm/trunk/test/Transforms/InstCombine/malloc3.ll Added: llvm/trunk/test/Transforms/InstCombine/malloc3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/malloc3.ll?rev=42890&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/malloc3.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/malloc3.ll Fri Oct 12 00:29:53 2007 @@ -0,0 +1,26 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {malloc.*struct.foo} | count 2 +; PR1728 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i686-apple-darwin8" + %struct.foo = type { %struct.foo*, [10 x i32] } + at .str = internal constant [21 x i8] c"tmp = %p, next = %p\0A\00" ; <[21 x i8]*> [#uses=1] + +define i32 @main() { +entry: + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + %tmp1 = malloc i8, i32 44 ; [#uses=1] + %tmp12 = bitcast i8* %tmp1 to %struct.foo* ; <%struct.foo*> [#uses=3] + %tmp3 = malloc i8, i32 44 ; [#uses=1] + %tmp34 = bitcast i8* %tmp3 to %struct.foo* ; <%struct.foo*> [#uses=1] + %tmp6 = getelementptr %struct.foo* %tmp12, i32 0, i32 0 ; <%struct.foo**> [#uses=1] + store %struct.foo* %tmp34, %struct.foo** %tmp6, align 4 + %tmp8 = getelementptr %struct.foo* %tmp12, i32 0, i32 0 ; <%struct.foo**> [#uses=1] + %tmp9 = load %struct.foo** %tmp8, align 4 ; <%struct.foo*> [#uses=1] + %tmp10 = getelementptr [21 x i8]* @.str, i32 0, i32 0 ; [#uses=1] + %tmp13 = call i32 (i8*, ...)* @printf( i8* %tmp10, %struct.foo* %tmp12, %struct.foo* %tmp9 ) ; [#uses=0] + ret i32 undef +} + +declare i32 @printf(i8*, ...) + From sabre at nondot.org Fri Oct 12 00:30:59 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 12 Oct 2007 05:30:59 -0000 Subject: [llvm-commits] [llvm] r42891 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200710120530.l9C5UxGo024668@zion.cs.uiuc.edu> Author: lattner Date: Fri Oct 12 00:30:59 2007 New Revision: 42891 URL: http://llvm.org/viewvc/llvm-project?rev=42891&view=rev Log: Fix some 80 column violations. Fix DecomposeSimpleLinearExpr to handle simple constants better. Don't nuke gep(bitcast(allocation)) if the bitcast(allocation) will fold the allocation. This fixes PR1728 and Instcombine/malloc3.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=42891&r1=42890&r2=42891&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Fri Oct 12 00:30:59 2007 @@ -6190,33 +6190,29 @@ assert(Val->getType() == Type::Int32Ty && "Unexpected allocation size type!"); if (ConstantInt *CI = dyn_cast(Val)) { Offset = CI->getZExtValue(); - Scale = 1; + Scale = 0; return ConstantInt::get(Type::Int32Ty, 0); - } else if (Instruction *I = dyn_cast(Val)) { - if (I->getNumOperands() == 2) { - if (ConstantInt *CUI = dyn_cast(I->getOperand(1))) { - if (I->getOpcode() == Instruction::Shl) { - // This is a value scaled by '1 << the shift amt'. - Scale = 1U << CUI->getZExtValue(); - Offset = 0; - return I->getOperand(0); - } else if (I->getOpcode() == Instruction::Mul) { - // This value is scaled by 'CUI'. - Scale = CUI->getZExtValue(); - Offset = 0; - return I->getOperand(0); - } else if (I->getOpcode() == Instruction::Add) { - // We have X+C. Check to see if we really have (X*C2)+C1, - // where C1 is divisible by C2. - unsigned SubScale; - Value *SubVal = - DecomposeSimpleLinearExpr(I->getOperand(0), SubScale, Offset); - Offset += CUI->getZExtValue(); - if (SubScale > 1 && (Offset % SubScale == 0)) { - Scale = SubScale; - return SubVal; - } - } + } else if (BinaryOperator *I = dyn_cast(Val)) { + if (ConstantInt *RHS = dyn_cast(I->getOperand(1))) { + if (I->getOpcode() == Instruction::Shl) { + // This is a value scaled by '1 << the shift amt'. + Scale = 1U << RHS->getZExtValue(); + Offset = 0; + return I->getOperand(0); + } else if (I->getOpcode() == Instruction::Mul) { + // This value is scaled by 'RHS'. + Scale = RHS->getZExtValue(); + Offset = 0; + return I->getOperand(0); + } else if (I->getOpcode() == Instruction::Add) { + // We have X+C. Check to see if we really have (X*C2)+C1, + // where C1 is divisible by C2. + unsigned SubScale; + Value *SubVal = + DecomposeSimpleLinearExpr(I->getOperand(0), SubScale, Offset); + Offset += RHS->getZExtValue(); + Scale = SubScale; + return SubVal; } } } @@ -7670,7 +7666,8 @@ Changed = true; } - // If MemCpyInst length is 1/2/4/8 bytes then replace memcpy with load/store + // If MemCpyInst length is 1/2/4/8 bytes then replace memcpy with + // load/store. ConstantInt *MemOpLength = dyn_cast(CI.getOperand(3)); if (isa(MI)) if (MemOpLength) { @@ -7704,10 +7701,11 @@ if (Size == 1) NewPtrTy = PointerType::get(Type::Int64Ty); } - if (NewPtrTy) - { - Value *Src = InsertCastBefore(Instruction::BitCast, CI.getOperand(2), NewPtrTy, CI); - Value *Dest = InsertCastBefore(Instruction::BitCast, CI.getOperand(1), NewPtrTy, CI); + if (NewPtrTy) { + Value *Src = + InsertCastBefore(Instruction::BitCast,CI.getOperand(2),NewPtrTy,CI); + Value *Dest = + InsertCastBefore(Instruction::BitCast,CI.getOperand(1),NewPtrTy,CI); Value *L = new LoadInst(Src, "tmp", false, Align, &CI); Value *NS = new StoreInst(L, Dest, false, Align, &CI); CI.replaceAllUsesWith(NS); @@ -8639,10 +8637,19 @@ // If this GEP instruction doesn't move the pointer, and if the input operand // is a bitcast of another pointer, just replace the GEP with a bitcast of the // real input to the dest type. - if (GEP.hasAllZeroIndices() && isa(GEP.getOperand(0))) - return new BitCastInst(cast(GEP.getOperand(0))->getOperand(0), - GEP.getType()); - + if (GEP.hasAllZeroIndices()) { + if (BitCastInst *BCI = dyn_cast(GEP.getOperand(0))) { + // If the bitcast is of an allocation, and the allocation will be + // converted to match the type of the cast, don't touch this. + if (isa(BCI->getOperand(0))) { + // See if the bitcast simplifies, if so, don't nuke this GEP yet. + if (Instruction *I = visitBitCast(*BCI)) + return &GEP; + } + return new BitCastInst(BCI->getOperand(0), GEP.getType()); + } + } + // Combine Indices - If the source pointer to this getelementptr instruction // is a getelementptr instruction, combine the indices of the two // getelementptr instructions into a single instruction. From clattner at apple.com Fri Oct 12 00:40:46 2007 From: clattner at apple.com (Chris Lattner) Date: Thu, 11 Oct 2007 22:40:46 -0700 Subject: [llvm-commits] [llvm] r42885 - in /llvm/trunk: include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/X86/vector-intrinsics.ll In-Reply-To: <200710120001.l9C01MnW011262@zion.cs.uiuc.edu> References: <200710120001.l9C01MnW011262@zion.cs.uiuc.edu> Message-ID: <81C9E74E-3A7D-40E8-A61B-B8203F92941B@apple.com> On Oct 11, 2007, at 5:01 PM, Dan Gohman wrote: > Author: djg > Date: Thu Oct 11 19:01:22 2007 > New Revision: 42885 > > URL: http://llvm.org/viewvc/llvm-project?rev=42885&view=rev > Log: > Add intrinsics for sin, cos, and pow. These use llvm_anyfloat_ty, > and so > may be overloaded with vector types. And add a testcase for codegen > for > these. Nifty. Please document these in langref.html. Some thoughts: 1) what are the precision guarantees of these operators? Are they guaranteed to be as precise as libm unless "-ffast-math" is provided? 2) should the front-end lower sin/cos/pow and friends to these? 3) does llvm.pow set errno? -Chris > Added: > llvm/trunk/test/CodeGen/X86/vector-intrinsics.ll > Modified: > llvm/trunk/include/llvm/Intrinsics.td > llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > > Modified: llvm/trunk/include/llvm/Intrinsics.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ > Intrinsics.td?rev=42885&r1=42884&r2=42885&view=diff > > ====================================================================== > ======== > --- llvm/trunk/include/llvm/Intrinsics.td (original) > +++ llvm/trunk/include/llvm/Intrinsics.td Thu Oct 11 19:01:22 2007 > @@ -184,6 +184,10 @@ > let Properties = [IntrNoMem] in { > def int_sqrt : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>; > def int_powi : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>, > llvm_i32_ty]>; > + def int_sin : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>; > + def int_cos : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>; > + def int_pow : Intrinsic<[llvm_anyfloat_ty, > + LLVMMatchType<0>, LLVMMatchType<0>]>; > } > > // NOTE: these are internal interfaces. > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ > SelectionDAG/SelectionDAGISel.cpp? > rev=42885&r1=42884&r2=42885&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu > Oct 11 19:01:22 2007 > @@ -2807,6 +2807,22 @@ > getValue(I.getOperand(1)), > getValue(I.getOperand(2)))); > return 0; > + case Intrinsic::sin: > + setValue(&I, DAG.getNode(ISD::FSIN, > + getValue(I.getOperand(1)).getValueType > (), > + getValue(I.getOperand(1)))); > + return 0; > + case Intrinsic::cos: > + setValue(&I, DAG.getNode(ISD::FCOS, > + getValue(I.getOperand(1)).getValueType > (), > + getValue(I.getOperand(1)))); > + return 0; > + case Intrinsic::pow: > + setValue(&I, DAG.getNode(ISD::FPOW, > + getValue(I.getOperand(1)).getValueType > (), > + getValue(I.getOperand(1)), > + getValue(I.getOperand(2)))); > + return 0; > case Intrinsic::pcmarker: { > SDOperand Tmp = getValue(I.getOperand(1)); > DAG.setRoot(DAG.getNode(ISD::PCMARKER, MVT::Other, getRoot(), > Tmp)); > > Added: llvm/trunk/test/CodeGen/X86/vector-intrinsics.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ > X86/vector-intrinsics.ll?rev=42885&view=auto > > ====================================================================== > ======== > --- llvm/trunk/test/CodeGen/X86/vector-intrinsics.ll (added) > +++ llvm/trunk/test/CodeGen/X86/vector-intrinsics.ll Thu Oct 11 > 19:01:22 2007 > @@ -0,0 +1,27 @@ > +; RUN: llvm-as < %s | llc -march=x86-64 | grep call | count 16 > + > +declare <4 x double> @llvm.sin.v4f64(<4 x double> %p) > +declare <4 x double> @llvm.cos.v4f64(<4 x double> %p) > +declare <4 x double> @llvm.pow.v4f64(<4 x double> %p, <4 x double> > %q) > +declare <4 x double> @llvm.powi.v4f64(<4 x double> %p, i32) > + > +define <4 x double> @foo(<4 x double> %p) > +{ > + %t = call <4 x double> @llvm.sin.v4f64(<4 x double> %p) > + ret <4 x double> %t > +} > +define <4 x double> @goo(<4 x double> %p) > +{ > + %t = call <4 x double> @llvm.cos.v4f64(<4 x double> %p) > + ret <4 x double> %t > +} > +define <4 x double> @moo(<4 x double> %p, <4 x double> %q) > +{ > + %t = call <4 x double> @llvm.pow.v4f64(<4 x double> %p, <4 x > double> %q) > + ret <4 x double> %t > +} > +define <4 x double> @zoo(<4 x double> %p, i32 %q) > +{ > + %t = call <4 x double> @llvm.powi.v4f64(<4 x double> %p, i32 %q) > + ret <4 x double> %t > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From ggreif at gmail.com Fri Oct 12 02:44:55 2007 From: ggreif at gmail.com (Gabor Greif) Date: Fri, 12 Oct 2007 07:44:55 -0000 Subject: [llvm-commits] [llvm] r42892 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200710120744.l9C7itBp003237@zion.cs.uiuc.edu> Author: ggreif Date: Fri Oct 12 02:44:54 2007 New Revision: 42892 URL: http://llvm.org/viewvc/llvm-project?rev=42892&view=rev Log: eliminate warning Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=42892&r1=42891&r2=42892&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Fri Oct 12 02:44:54 2007 @@ -8643,7 +8643,7 @@ // converted to match the type of the cast, don't touch this. if (isa(BCI->getOperand(0))) { // See if the bitcast simplifies, if so, don't nuke this GEP yet. - if (Instruction *I = visitBitCast(*BCI)) + if (visitBitCast(*BCI)) return &GEP; } return new BitCastInst(BCI->getOperand(0), GEP.getType()); From arnold.schwaighofer at gmail.com Fri Oct 12 02:49:48 2007 From: arnold.schwaighofer at gmail.com (Arnold Schwaighofer) Date: Fri, 12 Oct 2007 07:49:48 -0000 Subject: [llvm-commits] [llvm] r42893 - /llvm/trunk/test/CodeGen/X86/tailcall1.ll Message-ID: <200710120749.l9C7nmv1003345@zion.cs.uiuc.edu> Author: arnolds Date: Fri Oct 12 02:49:48 2007 New Revision: 42893 URL: http://llvm.org/viewvc/llvm-project?rev=42893&view=rev Log: Added missing -march=x86 flag. Modified: llvm/trunk/test/CodeGen/X86/tailcall1.ll Modified: llvm/trunk/test/CodeGen/X86/tailcall1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcall1.ll?rev=42893&r1=42892&r2=42893&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tailcall1.ll (original) +++ llvm/trunk/test/CodeGen/X86/tailcall1.ll Fri Oct 12 02:49:48 2007 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -tailcallopt | grep TAILCALL +; RUN: llvm-as < %s | llc -march=x86 -tailcallopt | grep TAILCALL define fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4) { entry: ret i32 %a3 From evan.cheng at apple.com Fri Oct 12 02:55:53 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 Oct 2007 07:55:53 -0000 Subject: [llvm-commits] [llvm] r42894 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200710120755.l9C7tr2R003496@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 02:55:53 2007 New Revision: 42894 URL: http://llvm.org/viewvc/llvm-project?rev=42894&view=rev Log: Flag MOV32to32_ with EXTRACT_SUBREG. They should not be scheduled apart. Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=42894&r1=42893&r2=42894&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Fri Oct 12 02:55:53 2007 @@ -1000,8 +1000,9 @@ VT = MVT::i32; break; } - N0 = - SDOperand(CurDAG->getTargetNode(Opc, VT, N0), 0); + N0 = SDOperand(CurDAG->getTargetNode(Opc, VT, MVT::Flag, N0), 0); + return CurDAG->getTargetNode(X86::EXTRACT_SUBREG, + VT, N0, SRIdx, N0.getValue(1)); } break; case MVT::i16: @@ -1010,11 +1011,9 @@ case MVT::i32: SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3 break; - default: assert(0 && "Unknown truncate!"); + default: assert(0 && "Unknown truncate!"); break; } - return CurDAG->getTargetNode(X86::EXTRACT_SUBREG, - VT, - N0, SRIdx); + return CurDAG->getTargetNode(X86::EXTRACT_SUBREG, VT, N0, SRIdx); } @@ -1382,7 +1381,8 @@ default: assert(0 && "Unknown any_extend!"); } if (SRIdx.Val) { - SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG, NVT, N0, SRIdx); + SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG, + NVT, N0, SRIdx); #ifndef NDEBUG DOUT << std::string(Indent-2, ' ') << "=> "; From evan.cheng at apple.com Fri Oct 12 03:38:01 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 Oct 2007 08:38:01 -0000 Subject: [llvm-commits] [llvm] r42895 - /llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <200710120838.l9C8c1d0004640@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 03:38:01 2007 New Revision: 42895 URL: http://llvm.org/viewvc/llvm-project?rev=42895&view=rev Log: Fold load / store into MOV32to32_ and MOV16to16_. Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=42895&r1=42894&r2=42895&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Fri Oct 12 03:38:01 2007 @@ -268,8 +268,10 @@ { X86::JMP64r, X86::JMP64m, 1 }, { X86::MOV16ri, X86::MOV16mi, 0 }, { X86::MOV16rr, X86::MOV16mr, 0 }, + { X86::MOV16to16_, X86::MOV16_mr, 0 }, { X86::MOV32ri, X86::MOV32mi, 0 }, { X86::MOV32rr, X86::MOV32mr, 0 }, + { X86::MOV32to32_, X86::MOV32_mr, 0 }, { X86::MOV64ri32, X86::MOV64mi32, 0 }, { X86::MOV64rr, X86::MOV64mr, 0 }, { X86::MOV8ri, X86::MOV8mi, 0 }, @@ -379,7 +381,9 @@ { X86::Int_UCOMISDrr, X86::Int_UCOMISDrm }, { X86::Int_UCOMISSrr, X86::Int_UCOMISSrm }, { X86::MOV16rr, X86::MOV16rm }, + { X86::MOV16to16_, X86::MOV16_rm }, { X86::MOV32rr, X86::MOV32rm }, + { X86::MOV32to32_, X86::MOV32_rm }, { X86::MOV64rr, X86::MOV64rm }, { X86::MOV64toPQIrr, X86::MOV64toPQIrm }, { X86::MOV64toSDrr, X86::MOV64toSDrm }, From evan.cheng at apple.com Fri Oct 12 03:39:03 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 Oct 2007 08:39:03 -0000 Subject: [llvm-commits] [llvm] r42896 - /llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200710120839.l9C8d3tM004678@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 03:39:02 2007 New Revision: 42896 URL: http://llvm.org/viewvc/llvm-project?rev=42896&view=rev Log: Fix typos. Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=42896&r1=42895&r2=42896&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Fri Oct 12 03:39:02 2007 @@ -3729,7 +3729,7 @@ << " SDOperand Tmp = CurDAG->getTargetConstant(C, MVT::i32);\n" << " AddToISelQueue(N0);\n" << " return CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG,\n" - << " N.getValueType(), N0, Tmp);\n" + << " N.getValueType(), N0, Tmp);\n" << "}\n\n"; OS << "SDNode *Select_INSERT_SUBREG(const SDOperand &N) {\n" @@ -3740,12 +3740,12 @@ << " SDOperand Tmp = CurDAG->getTargetConstant(C, MVT::i32);\n" << " AddToISelQueue(N1);\n" << " if (N0.getOpcode() == ISD::UNDEF) {\n" - << " return CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG,\n" - << " N.getValueType(), N1, Tmp);\n" + << " return CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG,\n" + << " N.getValueType(), N1, Tmp);\n" << " } else {\n" << " AddToISelQueue(N0);\n" - << " return CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG,\n" - << " N.getValueType(), N0, N1, Tmp);\n" + << " return CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG,\n" + << " N.getValueType(), N0, N1, Tmp);\n" << " }\n" << "}\n\n"; From evan.cheng at apple.com Fri Oct 12 03:40:44 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 Oct 2007 08:40:44 -0000 Subject: [llvm-commits] [llvm] r42897 - /llvm/trunk/include/llvm/CodeGen/RegisterCoalescer.h Message-ID: <200710120840.l9C8eiR9004741@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 03:40:44 2007 New Revision: 42897 URL: http://llvm.org/viewvc/llvm-project?rev=42897&view=rev Log: Cosmetic. Modified: llvm/trunk/include/llvm/CodeGen/RegisterCoalescer.h Modified: llvm/trunk/include/llvm/CodeGen/RegisterCoalescer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RegisterCoalescer.h?rev=42897&r1=42896&r2=42897&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/RegisterCoalescer.h (original) +++ llvm/trunk/include/llvm/CodeGen/RegisterCoalescer.h Fri Oct 12 03:40:44 2007 @@ -143,7 +143,7 @@ /// about which copies to coalesce should be made by the /// coalescer. virtual bool isLegalToCoalesce(const MachineInstr &inst) const { - return(true); + return true; } }; } From evan.cheng at apple.com Fri Oct 12 03:45:28 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 Oct 2007 08:45:28 -0000 Subject: [llvm-commits] [llvm] r42898 - /llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Message-ID: <200710120845.l9C8jSJ8005273@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 03:45:27 2007 New Revision: 42898 URL: http://llvm.org/viewvc/llvm-project?rev=42898&view=rev Log: Some clean up. Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp?rev=42898&r1=42897&r2=42898&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Fri Oct 12 03:45:27 2007 @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "regalloc" -#include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "PhysRegTracker.h" #include "VirtRegMap.h" @@ -216,10 +215,8 @@ // Rewrite spill code and update the PhysRegsUsed set. spiller_->runOnMachineFunction(*mf_, *vrm_); - vrm_.reset(); // Free the VirtRegMap - while (!unhandled_.empty()) unhandled_.pop(); fixed_.clear(); active_.clear(); From evan.cheng at apple.com Fri Oct 12 03:50:36 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 Oct 2007 08:50:36 -0000 Subject: [llvm-commits] [llvm] r42899 - in /llvm/trunk: include/llvm/CodeGen/LiveInterval.h include/llvm/CodeGen/LiveIntervalAnalysis.h include/llvm/CodeGen/MachineInstr.h include/llvm/CodeGen/SSARegMap.h include/llvm/CodeGen/SimpleRegisterCoalescing.h lib/CodeGen/LiveInterval.cpp lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/MachineInstr.cpp lib/CodeGen/SelectionDAG/ScheduleDAG.cpp lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp lib/CodeGen/SimpleRegisterCoalescing.cpp lib/CodeGen/VirtRegMap.cpp Message-ID: <200710120850.l9C8obdG005495@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 03:50:34 2007 New Revision: 42899 URL: http://llvm.org/viewvc/llvm-project?rev=42899&view=rev Log: EXTRACT_SUBREG coalescing support. The coalescer now treats EXTRACT_SUBREG like (almost) a register copy. However, it always coalesced to the register of the RHS (the super-register). All uses of the result of a EXTRACT_SUBREG are sub- register uses which adds subtle complications to load folding, spiller rewrite, etc. Modified: llvm/trunk/include/llvm/CodeGen/LiveInterval.h llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h llvm/trunk/include/llvm/CodeGen/MachineInstr.h llvm/trunk/include/llvm/CodeGen/SSARegMap.h llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h llvm/trunk/lib/CodeGen/LiveInterval.cpp llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/MachineInstr.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp llvm/trunk/lib/CodeGen/VirtRegMap.cpp Modified: llvm/trunk/include/llvm/CodeGen/LiveInterval.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveInterval.h?rev=42899&r1=42898&r2=42899&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveInterval.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveInterval.h Fri Oct 12 03:50:34 2007 @@ -155,7 +155,7 @@ /// copyValNumInfo - Copy the value number info for one value number to /// another. - void copyValNumInfo(VNInfo *DstValNo, VNInfo *SrcValNo) { + void copyValNumInfo(VNInfo *DstValNo, const VNInfo *SrcValNo) { DstValNo->def = SrcValNo->def; DstValNo->reg = SrcValNo->reg; DstValNo->kills = SrcValNo->kills; @@ -241,11 +241,23 @@ void MergeInClobberRanges(const LiveInterval &Clobbers, BumpPtrAllocator &VNInfoAllocator); - /// MergeRangesInAsValue - Merge all of the intervals in RHS into this live - /// interval as the specified value number. The LiveRanges in RHS are + /// MergeRangesInAsValue - Merge all of the live ranges in RHS into this + /// live interval as the specified value number. The LiveRanges in RHS are /// allowed to overlap with LiveRanges in the current interval, but only if /// the overlapping LiveRanges have the specified value number. void MergeRangesInAsValue(const LiveInterval &RHS, VNInfo *LHSValNo); + + /// MergeValueInAsValue - Merge all of the live ranges of a specific val# + /// in RHS into this live interval as the specified value number. + /// The LiveRanges in RHS are allowed to overlap with LiveRanges in the + /// current interval, but only if the overlapping LiveRanges have the + /// specified value number. + void MergeValueInAsValue(const LiveInterval &RHS, + VNInfo *RHSValNo, VNInfo *LHSValNo); + + /// Copy - Copy the specified live interval. This copies all the fields + /// except for the register of the interval. + void Copy(const LiveInterval &RHS, BumpPtrAllocator &VNInfoAllocator); bool empty() const { return ranges.empty(); } Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=42899&r1=42898&r2=42899&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Fri Oct 12 03:50:34 2007 @@ -167,11 +167,6 @@ return I->second; } - /// CreateNewLiveInterval - Create a new live interval with the given live - /// ranges. The new live interval will have an infinite spill weight. - LiveInterval &CreateNewLiveInterval(const LiveInterval *LI, - const std::vector &LRs); - std::vector addIntervalsForSpills(const LiveInterval& i, VirtRegMap& vrm, unsigned reg); @@ -254,8 +249,8 @@ /// MI. If it is successul, MI is updated with the newly created MI and /// returns true. bool tryFoldMemoryOperand(MachineInstr* &MI, VirtRegMap &vrm, - unsigned index, unsigned i, bool isSS, - MachineInstr *DefMI, int slot, unsigned reg); + MachineInstr *DefMI, unsigned index, unsigned i, + bool isSS, int slot, unsigned reg); static LiveInterval createInterval(unsigned Reg); Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstr.h?rev=42899&r1=42898&r2=42899&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineInstr.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h Fri Oct 12 03:50:34 2007 @@ -418,6 +418,10 @@ /// none is found. int findFirstPredOperandIdx() const; + /// isRegReDefinedByTwoAddr - Returns true if the Reg re-definition is due + /// to two addr elimination. + bool isRegReDefinedByTwoAddr(unsigned Reg) const; + /// copyKillDeadInfo - Copies kill / dead operand properties from MI. /// void copyKillDeadInfo(const MachineInstr *MI); Modified: llvm/trunk/include/llvm/CodeGen/SSARegMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SSARegMap.h?rev=42899&r1=42898&r2=42899&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SSARegMap.h (original) +++ llvm/trunk/include/llvm/CodeGen/SSARegMap.h Fri Oct 12 03:50:34 2007 @@ -26,6 +26,7 @@ class SSARegMap { IndexedMap RegClassMap; + IndexedMap, VirtReg2IndexFunctor> RegSubIdxMap; unsigned NextRegNum; public: @@ -42,12 +43,30 @@ assert(RegClass && "Cannot create register without RegClass!"); RegClassMap.grow(NextRegNum); RegClassMap[NextRegNum] = RegClass; + RegSubIdxMap.grow(NextRegNum); + RegSubIdxMap[NextRegNum] = std::make_pair(0,0); return NextRegNum++; } unsigned getLastVirtReg() const { return NextRegNum - 1; } + + void setIsSubRegister(unsigned Reg, unsigned SuperReg, unsigned SubIdx) { + RegSubIdxMap[Reg] = std::make_pair(SuperReg, SubIdx); + } + + bool isSubRegister(unsigned Reg) const { + return RegSubIdxMap[Reg].first != 0; + } + + unsigned getSuperRegister(unsigned Reg) const { + return RegSubIdxMap[Reg].first; + } + + unsigned getSubRegisterIndex(unsigned Reg) const { + return RegSubIdxMap[Reg].second; + } }; } // End llvm namespace Modified: llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h?rev=42899&r1=42898&r2=42899&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h (original) +++ llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h Fri Oct 12 03:50:34 2007 @@ -47,6 +47,10 @@ /// with other intervals. BitVector JoinedLIs; + /// SubRegIdxes - Keep track of sub-register and sub-indexes. + /// + std::vector > SubRegIdxes; + public: static char ID; // Pass identifcation, replacement for typeid SimpleRegisterCoalescing() : MachineFunctionPass((intptr_t)&ID) {} Modified: llvm/trunk/lib/CodeGen/LiveInterval.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveInterval.cpp?rev=42899&r1=42898&r2=42899&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveInterval.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveInterval.cpp Fri Oct 12 03:50:34 2007 @@ -383,6 +383,26 @@ } +/// MergeValueInAsValue - Merge all of the live ranges of a specific val# +/// in RHS into this live interval as the specified value number. +/// The LiveRanges in RHS are allowed to overlap with LiveRanges in the +/// current interval, but only if the overlapping LiveRanges have the +/// specified value number. +void LiveInterval::MergeValueInAsValue(const LiveInterval &RHS, + VNInfo *RHSValNo, VNInfo *LHSValNo) { + // TODO: Make this more efficient. + iterator InsertPos = begin(); + for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) { + if (I->valno != RHSValNo) + continue; + // Map the valno in the other live range to the current live range. + LiveRange Tmp = *I; + Tmp.valno = LHSValNo; + InsertPos = addRangeFrom(Tmp, InsertPos); + } +} + + /// MergeInClobberRanges - For any live ranges that are not defined in the /// current interval, but are defined in the Clobbers interval, mark them /// used with an unknown definition value. @@ -485,6 +505,23 @@ } } +void LiveInterval::Copy(const LiveInterval &RHS, + BumpPtrAllocator &VNInfoAllocator) { + ranges.clear(); + valnos.clear(); + preference = RHS.preference; + weight = RHS.weight; + for (unsigned i = 0, e = RHS.getNumValNums(); i != e; ++i) { + const VNInfo *VNI = RHS.getValNumInfo(i); + VNInfo *NewVNI = getNextValue(~0U, 0, VNInfoAllocator); + copyValNumInfo(NewVNI, VNI); + } + for (unsigned i = 0, e = RHS.ranges.size(); i != e; ++i) { + const LiveRange &LR = RHS.ranges[i]; + addRange(LiveRange(LR.start, LR.end, getValNumInfo(LR.valno->id))); + } +} + unsigned LiveInterval::getSize() const { unsigned Sum = 0; for (const_iterator I = begin(), E = end(); I != E; ++I) Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=42899&r1=42898&r2=42899&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Fri Oct 12 03:50:34 2007 @@ -136,75 +136,6 @@ } } -// Not called? -/// CreateNewLiveInterval - Create a new live interval with the given live -/// ranges. The new live interval will have an infinite spill weight. -LiveInterval& -LiveIntervals::CreateNewLiveInterval(const LiveInterval *LI, - const std::vector &LRs) { - const TargetRegisterClass *RC = mf_->getSSARegMap()->getRegClass(LI->reg); - - // Create a new virtual register for the spill interval. - unsigned NewVReg = mf_->getSSARegMap()->createVirtualRegister(RC); - - // Replace the old virtual registers in the machine operands with the shiny - // new one. - for (std::vector::const_iterator - I = LRs.begin(), E = LRs.end(); I != E; ++I) { - unsigned Index = getBaseIndex(I->start); - unsigned End = getBaseIndex(I->end - 1) + InstrSlots::NUM; - - for (; Index != End; Index += InstrSlots::NUM) { - // Skip deleted instructions - while (Index != End && !getInstructionFromIndex(Index)) - Index += InstrSlots::NUM; - - if (Index == End) break; - - MachineInstr *MI = getInstructionFromIndex(Index); - - for (unsigned J = 0, e = MI->getNumOperands(); J != e; ++J) { - MachineOperand &MOp = MI->getOperand(J); - if (MOp.isRegister() && MOp.getReg() == LI->reg) - MOp.setReg(NewVReg); - } - } - } - - LiveInterval &NewLI = getOrCreateInterval(NewVReg); - - // The spill weight is now infinity as it cannot be spilled again - NewLI.weight = float(HUGE_VAL); - - for (std::vector::const_iterator - I = LRs.begin(), E = LRs.end(); I != E; ++I) { - DOUT << " Adding live range " << *I << " to new interval\n"; - NewLI.addRange(*I); - } - - DOUT << "Created new live interval " << NewLI << "\n"; - return NewLI; -} - -/// isReDefinedByTwoAddr - Returns true if the Reg re-definition is due to -/// two addr elimination. -static bool isReDefinedByTwoAddr(MachineInstr *MI, unsigned Reg, - const TargetInstrInfo *TII) { - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO1 = MI->getOperand(i); - if (MO1.isRegister() && MO1.isDef() && MO1.getReg() == Reg) { - for (unsigned j = i+1; j < e; ++j) { - MachineOperand &MO2 = MI->getOperand(j); - if (MO2.isRegister() && MO2.isUse() && MO2.getReg() == Reg && - MI->getInstrDescriptor()-> - getOperandConstraint(j, TOI::TIED_TO) == (int)i) - return true; - } - } - } - return false; -} - /// isReMaterializable - Returns true if the definition MI of the specified /// val# of the specified interval is re-materializable. bool LiveIntervals::isReMaterializable(const LiveInterval &li, @@ -232,7 +163,7 @@ continue; // Dead val#. MachineInstr *DefMI = (DefIdx == ~0u) ? NULL : getInstructionFromIndex(DefIdx); - if (DefMI && isReDefinedByTwoAddr(DefMI, li.reg, tii_)) + if (DefMI && DefMI->isRegReDefinedByTwoAddr(li.reg)) return false; } return true; @@ -243,9 +174,9 @@ /// MI. If it is successul, MI is updated with the newly created MI and /// returns true. bool LiveIntervals::tryFoldMemoryOperand(MachineInstr* &MI, VirtRegMap &vrm, + MachineInstr *DefMI, unsigned index, unsigned i, - bool isSS, MachineInstr *DefMI, - int slot, unsigned reg) { + bool isSS, int slot, unsigned reg) { MachineInstr *fmi = isSS ? mri_->foldMemoryOperand(MI, i, slot) : mri_->foldMemoryOperand(MI, i, DefMI); @@ -281,7 +212,8 @@ li.print(DOUT, mri_); DOUT << '\n'; - const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(li.reg); + SSARegMap *RegMap = mf_->getSSARegMap(); + const TargetRegisterClass* rc = RegMap->getRegClass(li.reg); unsigned NumValNums = li.getNumValNums(); SmallVector ReMatDefs; @@ -364,113 +296,126 @@ RestartInstruction: for (unsigned i = 0; i != MI->getNumOperands(); ++i) { MachineOperand& mop = MI->getOperand(i); - if (mop.isRegister() && mop.getReg() == li.reg) { - if (DefIsReMat) { - // If this is the rematerializable definition MI itself and - // all of its uses are rematerialized, simply delete it. - if (MI == OrigDefMI) { - if (CanDelete) { - RemoveMachineInstrFromMaps(MI); - MI->eraseFromParent(); - break; - } else if (tryFoldMemoryOperand(MI, vrm, index, i, true, - DefMI, slot, li.reg)) { - // Folding the load/store can completely change the instruction - // in unpredictable ways, rescan it from the beginning. - goto RestartInstruction; - } - } else if (isLoad && - tryFoldMemoryOperand(MI, vrm, index, i, isLoadSS, - DefMI, LdSlot, li.reg)) - // Folding the load/store can completely change the - // instruction in unpredictable ways, rescan it from - // the beginning. - goto RestartInstruction; - } else { - if (tryFoldMemoryOperand(MI, vrm, index, i, true, DefMI, - slot, li.reg)) - // Folding the load/store can completely change the instruction in - // unpredictable ways, rescan it from the beginning. - goto RestartInstruction; + if (!mop.isRegister()) + continue; + unsigned Reg = mop.getReg(); + if (Reg == 0 || MRegisterInfo::isPhysicalRegister(Reg)) + continue; + bool isSubReg = RegMap->isSubRegister(Reg); + unsigned SubIdx = 0; + if (isSubReg) { + SubIdx = RegMap->getSubRegisterIndex(Reg); + Reg = RegMap->getSuperRegister(Reg); + } + if (Reg != li.reg) + continue; + + bool TryFold = !DefIsReMat; + bool FoldSS = true; + int FoldSlot = slot; + if (DefIsReMat) { + // If this is the rematerializable definition MI itself and + // all of its uses are rematerialized, simply delete it. + if (MI == OrigDefMI && CanDelete) { + RemoveMachineInstrFromMaps(MI); + MI->eraseFromParent(); + break; + } + + // If def for this use can't be rematerialized, then try folding. + TryFold = !OrigDefMI || (OrigDefMI && (MI == OrigDefMI || isLoad)); + if (isLoad) { + // Try fold loads (from stack slot, constant pool, etc.) into uses. + FoldSS = isLoadSS; + FoldSlot = LdSlot; } + } - // Create a new virtual register for the spill interval. - unsigned NewVReg = mf_->getSSARegMap()->createVirtualRegister(rc); + // FIXME: fold subreg use + if (!isSubReg && TryFold && + tryFoldMemoryOperand(MI, vrm, DefMI, index, i, FoldSS, FoldSlot, Reg)) + // Folding the load/store can completely change the instruction in + // unpredictable ways, rescan it from the beginning. + goto RestartInstruction; + + // Create a new virtual register for the spill interval. + unsigned NewVReg = RegMap->createVirtualRegister(rc); + if (isSubReg) + RegMap->setIsSubRegister(NewVReg, NewVReg, SubIdx); - // Scan all of the operands of this instruction rewriting operands - // to use NewVReg instead of li.reg as appropriate. We do this for - // two reasons: - // - // 1. If the instr reads the same spilled vreg multiple times, we - // want to reuse the NewVReg. - // 2. If the instr is a two-addr instruction, we are required to - // keep the src/dst regs pinned. - // - // Keep track of whether we replace a use and/or def so that we can - // create the spill interval with the appropriate range. - mop.setReg(NewVReg); + // Scan all of the operands of this instruction rewriting operands + // to use NewVReg instead of li.reg as appropriate. We do this for + // two reasons: + // + // 1. If the instr reads the same spilled vreg multiple times, we + // want to reuse the NewVReg. + // 2. If the instr is a two-addr instruction, we are required to + // keep the src/dst regs pinned. + // + // Keep track of whether we replace a use and/or def so that we can + // create the spill interval with the appropriate range. + mop.setReg(NewVReg); - bool HasUse = mop.isUse(); - bool HasDef = mop.isDef(); - for (unsigned j = i+1, e = MI->getNumOperands(); j != e; ++j) { - if (MI->getOperand(j).isRegister() && - MI->getOperand(j).getReg() == li.reg) { - MI->getOperand(j).setReg(NewVReg); - HasUse |= MI->getOperand(j).isUse(); - HasDef |= MI->getOperand(j).isDef(); - } + bool HasUse = mop.isUse(); + bool HasDef = mop.isDef(); + for (unsigned j = i+1, e = MI->getNumOperands(); j != e; ++j) { + if (MI->getOperand(j).isRegister() && + MI->getOperand(j).getReg() == li.reg) { + MI->getOperand(j).setReg(NewVReg); + HasUse |= MI->getOperand(j).isUse(); + HasDef |= MI->getOperand(j).isDef(); } + } - vrm.grow(); - if (DefIsReMat) { - vrm.setVirtIsReMaterialized(NewVReg, DefMI/*, CanDelete*/); - if (ReMatIds[I->valno->id] == VirtRegMap::MAX_STACK_SLOT) { - // Each valnum may have its own remat id. - ReMatIds[I->valno->id] = vrm.assignVirtReMatId(NewVReg); - } else { - vrm.assignVirtReMatId(NewVReg, ReMatIds[I->valno->id]); - } - if (!CanDelete || (HasUse && HasDef)) { - // If this is a two-addr instruction then its use operands are - // rematerializable but its def is not. It should be assigned a - // stack slot. - vrm.assignVirt2StackSlot(NewVReg, slot); - } + vrm.grow(); + if (DefIsReMat) { + vrm.setVirtIsReMaterialized(NewVReg, DefMI/*, CanDelete*/); + if (ReMatIds[I->valno->id] == VirtRegMap::MAX_STACK_SLOT) { + // Each valnum may have its own remat id. + ReMatIds[I->valno->id] = vrm.assignVirtReMatId(NewVReg); } else { + vrm.assignVirtReMatId(NewVReg, ReMatIds[I->valno->id]); + } + if (!CanDelete || (HasUse && HasDef)) { + // If this is a two-addr instruction then its use operands are + // rematerializable but its def is not. It should be assigned a + // stack slot. vrm.assignVirt2StackSlot(NewVReg, slot); } + } else { + vrm.assignVirt2StackSlot(NewVReg, slot); + } - // create a new register interval for this spill / remat. - LiveInterval &nI = getOrCreateInterval(NewVReg); - assert(nI.empty()); - - // the spill weight is now infinity as it - // cannot be spilled again - nI.weight = HUGE_VALF; - - if (HasUse) { - LiveRange LR(getLoadIndex(index), getUseIndex(index)+1, - nI.getNextValue(~0U, 0, VNInfoAllocator)); - DOUT << " +" << LR; - nI.addRange(LR); - } - if (HasDef) { - LiveRange LR(getDefIndex(index), getStoreIndex(index), - nI.getNextValue(~0U, 0, VNInfoAllocator)); - DOUT << " +" << LR; - nI.addRange(LR); - } + // create a new register interval for this spill / remat. + LiveInterval &nI = getOrCreateInterval(NewVReg); + assert(nI.empty()); + + // the spill weight is now infinity as it + // cannot be spilled again + nI.weight = HUGE_VALF; + + if (HasUse) { + LiveRange LR(getLoadIndex(index), getUseIndex(index)+1, + nI.getNextValue(~0U, 0, VNInfoAllocator)); + DOUT << " +" << LR; + nI.addRange(LR); + } + if (HasDef) { + LiveRange LR(getDefIndex(index), getStoreIndex(index), + nI.getNextValue(~0U, 0, VNInfoAllocator)); + DOUT << " +" << LR; + nI.addRange(LR); + } - added.push_back(&nI); + added.push_back(&nI); - // update live variables if it is available - if (lv_) - lv_->addVirtualRegisterKilled(NewVReg, MI); + // update live variables if it is available + if (lv_) + lv_->addVirtualRegisterKilled(NewVReg, MI); - DOUT << "\t\t\t\tadded new interval: "; - nI.print(DOUT, mri_); - DOUT << '\n'; - } + DOUT << "\t\t\t\tadded new interval: "; + nI.print(DOUT, mri_); + DOUT << '\n'; } } } @@ -501,10 +446,14 @@ unsigned defIndex = getDefIndex(MIIdx); VNInfo *ValNo; unsigned SrcReg, DstReg; - if (!tii_->isMoveInstr(*mi, SrcReg, DstReg)) - ValNo = interval.getNextValue(defIndex, 0, VNInfoAllocator); - else + if (tii_->isMoveInstr(*mi, SrcReg, DstReg)) ValNo = interval.getNextValue(defIndex, SrcReg, VNInfoAllocator); + else if (mi->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG || + mi->getOpcode() == TargetInstrInfo::INSERT_SUBREG) + ValNo = interval.getNextValue(defIndex, mi->getOperand(1).getReg(), + VNInfoAllocator); + else + ValNo = interval.getNextValue(defIndex, 0, VNInfoAllocator); assert(ValNo->id == 0 && "First value in interval is not 0?"); @@ -576,7 +525,7 @@ // must be due to phi elimination or two addr elimination. If this is // the result of two address elimination, then the vreg is one of the // def-and-use register operand. - if (isReDefinedByTwoAddr(mi, interval.reg, tii_)) { + if (mi->isRegReDefinedByTwoAddr(interval.reg)) { // If this is a two-address definition, then we have already processed // the live range. The only problem is that we didn't realize there // are actually two values in the live interval. Because of this we @@ -656,10 +605,13 @@ VNInfo *ValNo; unsigned SrcReg, DstReg; - if (!tii_->isMoveInstr(*mi, SrcReg, DstReg)) - ValNo = interval.getNextValue(defIndex, 0, VNInfoAllocator); - else + if (tii_->isMoveInstr(*mi, SrcReg, DstReg)) ValNo = interval.getNextValue(defIndex, SrcReg, VNInfoAllocator); + else if (mi->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) + ValNo = interval.getNextValue(defIndex, mi->getOperand(1).getReg(), + VNInfoAllocator); + else + ValNo = interval.getNextValue(defIndex, 0, VNInfoAllocator); unsigned killIndex = getInstructionIndex(&mbb->back()) + InstrSlots::NUM; LiveRange LR(defIndex, killIndex, ValNo); @@ -741,7 +693,9 @@ handleVirtualRegisterDef(MBB, MI, MIIdx, getOrCreateInterval(reg)); else if (allocatableRegs_[reg]) { unsigned SrcReg, DstReg; - if (!tii_->isMoveInstr(*MI, SrcReg, DstReg)) + if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) + SrcReg = MI->getOperand(1).getReg(); + else if (!tii_->isMoveInstr(*MI, SrcReg, DstReg)) SrcReg = 0; handlePhysicalRegisterDef(MBB, MI, MIIdx, getOrCreateInterval(reg), SrcReg); // Def of a register also defines its sub-registers. Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=42899&r1=42898&r2=42899&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Fri Oct 12 03:50:34 2007 @@ -220,6 +220,24 @@ return -1; } +/// isRegReDefinedByTwoAddr - Returns true if the Reg re-definition is due +/// to two addr elimination. +bool MachineInstr::isRegReDefinedByTwoAddr(unsigned Reg) const { + const TargetInstrDescriptor *TID = getInstrDescriptor(); + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + const MachineOperand &MO1 = getOperand(i); + if (MO1.isRegister() && MO1.isDef() && MO1.getReg() == Reg) { + for (unsigned j = i+1; j < e; ++j) { + const MachineOperand &MO2 = getOperand(j); + if (MO2.isRegister() && MO2.isUse() && MO2.getReg() == Reg && + TID->getOperandConstraint(j, TOI::TIED_TO) == (int)i) + return true; + } + } + } + return false; +} + /// copyKillDeadInfo - Copies kill / dead operand properties from MI. /// void MachineInstr::copyKillDeadInfo(const MachineInstr *MI) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=42899&r1=42898&r2=42899&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Oct 12 03:50:34 2007 @@ -567,9 +567,6 @@ // TODO: If the node is a use of a CopyFromReg from a physical register // fold the extract into the copy now - // TODO: Add tracking info to SSARegMap of which vregs are subregs - // to allow coalescing in the allocator - // Create the extract_subreg machine instruction. MachineInstr *MI = new MachineInstr(BB, TII->get(TargetInstrInfo::EXTRACT_SUBREG)); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=42899&r1=42898&r2=42899&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Fri Oct 12 03:50:34 2007 @@ -1097,6 +1097,11 @@ // CopyToReg should be close to its uses to facilitate coalescing and // avoid spilling. return 0; + else if (Opc == TargetInstrInfo::EXTRACT_SUBREG || + Opc == TargetInstrInfo::INSERT_SUBREG) + // EXTRACT_SUBREG / INSERT_SUBREG should be close to its use to + // facilitate coalescing. + return 0; else if (SU->NumSuccs == 0) // If SU does not have a use, i.e. it doesn't produce a value that would // be consumed (e.g. store), then it terminates a chain of computation. @@ -1308,6 +1313,14 @@ // Be conservative. Ignore if nodes aren't at the same depth. if (SuccSU->Depth != SU->Depth) continue; + if (!SuccSU->Node || !SuccSU->Node->isTargetOpcode()) + continue; + // Don't constraint extract_subreg / insert_subreg these may be + // coalesced away. We don't them close to their uses. + unsigned SuccOpc = SuccSU->Node->getTargetOpcode(); + if (SuccOpc == TargetInstrInfo::EXTRACT_SUBREG || + SuccOpc == TargetInstrInfo::INSERT_SUBREG) + continue; if ((!canClobber(SuccSU, DUSU) || (hasCopyToRegUse(SU) && !hasCopyToRegUse(SuccSU)) || (!SU->isCommutable && SuccSU->isCommutable)) && Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=42899&r1=42898&r2=42899&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Fri Oct 12 03:50:34 2007 @@ -226,11 +226,55 @@ DOUT << "\tDst reg is unallocatable physreg.\n"; return true; // Not coalescable. } - - // If they are not of the same register class, we cannot join them. - if (differingRegisterClasses(repSrcReg, repDstReg)) { + + bool isExtSubReg = CopyMI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG; + unsigned RealDstReg = 0; + if (isExtSubReg) { + unsigned SubIdx = CopyMI->getOperand(2).getImm(); + if (SrcIsPhys) + // r1024 = EXTRACT_SUBREG EAX, 0 then r1024 is really going to be + // coalesced with AX. + repSrcReg = mri_->getSubReg(repSrcReg, SubIdx); + else if (DstIsPhys) { + // If this is a extract_subreg where dst is a physical register, e.g. + // cl = EXTRACT_SUBREG reg1024, 1 + // then create and update the actual physical register allocated to RHS. + const TargetRegisterClass *RC = mf_->getSSARegMap()->getRegClass(SrcReg); + for (const unsigned *SRs = mri_->getSuperRegisters(repDstReg); + unsigned SR = *SRs; ++SRs) { + if (repDstReg == mri_->getSubReg(SR, SubIdx) && + RC->contains(SR)) { + RealDstReg = SR; + break; + } + } + assert(RealDstReg && "Invalid extra_subreg instruction!"); + + // For this type of EXTRACT_SUBREG, conservatively + // check if the live interval of the source register interfere with the + // actual super physical register we are trying to coalesce with. + LiveInterval &RHS = li_->getInterval(repSrcReg); + if (li_->hasInterval(RealDstReg) && + RHS.overlaps(li_->getInterval(RealDstReg))) { + DOUT << "Interfere with register "; + DEBUG(li_->getInterval(RealDstReg).print(DOUT, mri_)); + return true; // Not coalescable + } + for (const unsigned* SR = mri_->getSubRegisters(RealDstReg); *SR; ++SR) + if (li_->hasInterval(*SR) && RHS.overlaps(li_->getInterval(*SR))) { + DOUT << "Interfere with sub-register "; + DEBUG(li_->getInterval(*SR).print(DOUT, mri_)); + return true; + } + } + } else if (differingRegisterClasses(repSrcReg, repDstReg)) { + // If they are not of the same register class, we cannot join them. DOUT << "\tSrc/Dest are different register classes.\n"; - return true; // Not coalescable. + // Allow the coalescer to try again in case either side gets coalesced to + // a physical register that's compatible with the other side. e.g. + // r1024 = MOV32to32_ r1025 + // but later r1024 is assigned EAX then r1025 may be coalesced with EAX. + return false; } LiveInterval &SrcInt = li_->getInterval(repSrcReg); @@ -286,14 +330,14 @@ // virtual register. Once the coalescing is done, it cannot be broken and // these are not spillable! If the destination interval uses are far away, // think twice about coalescing them! - if (!mopd->isDead() && (SrcIsPhys || DstIsPhys)) { + if (!mopd->isDead() && (SrcIsPhys || DstIsPhys) && !isExtSubReg) { LiveInterval &JoinVInt = SrcIsPhys ? DstInt : SrcInt; unsigned JoinVReg = SrcIsPhys ? repDstReg : repSrcReg; unsigned JoinPReg = SrcIsPhys ? repSrcReg : repDstReg; const TargetRegisterClass *RC = mf_->getSSARegMap()->getRegClass(JoinVReg); unsigned Threshold = allocatableRCRegs_[RC].count(); - // If the virtual register live interval is long has it has low use desity, + // If the virtual register live interval is long but it has low use desity, // do not join them, instead mark the physical register as its allocation // preference. unsigned Length = JoinVInt.getSize() / InstrSlots::NUM; @@ -340,7 +384,7 @@ // Coalescing failed. // If we can eliminate the copy without merging the live ranges, do so now. - if (AdjustCopiesBackFrom(SrcInt, DstInt, CopyMI)) + if (!isExtSubReg && AdjustCopiesBackFrom(SrcInt, DstInt, CopyMI)) return true; // Otherwise, we are unable to join the intervals. @@ -368,9 +412,24 @@ unsetRegisterKills(I->start, I->end, repDstReg); } + // If this is a extract_subreg where dst is a physical register, e.g. + // cl = EXTRACT_SUBREG reg1024, 1 + // then create and update the actual physical register allocated to RHS. + if (RealDstReg) { + unsigned CopyIdx = li_->getInstructionIndex(CopyMI); + VNInfo *DstValNo = + ResDstInt->getLiveRangeContaining(li_->getUseIndex(CopyIdx))->valno; + LiveInterval &RealDstInt = li_->getOrCreateInterval(RealDstReg); + VNInfo *ValNo = RealDstInt.getNextValue(DstValNo->def, DstValNo->reg, + li_->getVNInfoAllocator()); + RealDstInt.addKills(ValNo, DstValNo->kills); + RealDstInt.MergeValueInAsValue(*ResDstInt, DstValNo, ValNo); + repDstReg = RealDstReg; + } + // Update the liveintervals of sub-registers. for (const unsigned *AS = mri_->getSubRegisters(repDstReg); *AS; ++AS) - li_->getInterval(*AS).MergeInClobberRanges(*ResSrcInt, + li_->getOrCreateInterval(*AS).MergeInClobberRanges(*ResSrcInt, li_->getVNInfoAllocator()); } else { // Merge use info if the destination is a virtual register. @@ -379,14 +438,25 @@ dVI.NumUses += sVI.NumUses; } - DOUT << "\n\t\tJoined. Result = "; ResDstInt->print(DOUT, mri_); - DOUT << "\n"; - // Remember these liveintervals have been joined. JoinedLIs.set(repSrcReg - MRegisterInfo::FirstVirtualRegister); if (MRegisterInfo::isVirtualRegister(repDstReg)) JoinedLIs.set(repDstReg - MRegisterInfo::FirstVirtualRegister); + if (isExtSubReg && !SrcIsPhys && !DstIsPhys) { + if (!Swapped) { + // Make sure we allocate the larger super-register. + ResSrcInt->Copy(*ResDstInt, li_->getVNInfoAllocator()); + std::swap(repSrcReg, repDstReg); + std::swap(ResSrcInt, ResDstInt); + } + SubRegIdxes.push_back(std::make_pair(repSrcReg, + CopyMI->getOperand(2).getImm())); + } + + DOUT << "\n\t\tJoined. Result = "; ResDstInt->print(DOUT, mri_); + DOUT << "\n"; + // repSrcReg is guarateed to be the register whose live interval that is // being merged. li_->removeInterval(repSrcReg); @@ -857,9 +927,13 @@ MII != E;) { MachineInstr *Inst = MII++; - // If this isn't a copy, we can't join intervals. + // If this isn't a copy nor a extract_subreg, we can't join intervals. unsigned SrcReg, DstReg; - if (!tii_->isMoveInstr(*Inst, SrcReg, DstReg)) continue; + if (Inst->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) { + DstReg = Inst->getOperand(0).getReg(); + SrcReg = Inst->getOperand(1).getReg(); + } else if (!tii_->isMoveInstr(*Inst, SrcReg, DstReg)) + continue; bool Done = JoinCopy(Inst, SrcReg, DstReg, PhysOnly); if (TryAgain && !Done) @@ -950,7 +1024,7 @@ /// Return true if the two specified registers belong to different register /// classes. The registers may be either phys or virt regs. bool SimpleRegisterCoalescing::differingRegisterClasses(unsigned RegA, - unsigned RegB) const { + unsigned RegB) const { // Get the register classes for the first reg. if (MRegisterInfo::isPhysicalRegister(RegA)) { @@ -1074,6 +1148,7 @@ void SimpleRegisterCoalescing::releaseMemory() { r2rMap_.clear(); JoinedLIs.clear(); + SubRegIdxes.clear(); } static bool isZeroLengthInterval(LiveInterval *li) { @@ -1101,7 +1176,8 @@ E = mri_->regclass_end(); I != E; ++I) allocatableRCRegs_.insert(std::make_pair(*I,mri_->getAllocatableSet(fn, *I))); - r2rMap_.grow(mf_->getSSARegMap()->getLastVirtReg()); + SSARegMap *RegMap = mf_->getSSARegMap(); + r2rMap_.grow(RegMap->getLastVirtReg()); // Join (coalesce) intervals if requested. if (EnableJoining) { @@ -1111,6 +1187,13 @@ I->second.print(DOUT, mri_); DOUT << "\n"; } + + // Track coalesced sub-registers. + while (!SubRegIdxes.empty()) { + std::pair RI = SubRegIdxes.back(); + SubRegIdxes.pop_back(); + mf_->getSSARegMap()->setIsSubRegister(RI.first, rep(RI.first), RI.second); + } } // perform a final pass over the instructions and compute spill @@ -1150,8 +1233,14 @@ if (mop.isRegister() && mop.getReg() && MRegisterInfo::isVirtualRegister(mop.getReg())) { // replace register with representative register - unsigned reg = rep(mop.getReg()); - mii->getOperand(i).setReg(reg); + unsigned OrigReg = mop.getReg(); + unsigned reg = rep(OrigReg); + // Don't rewrite if it is a sub-register of a virtual register. + if (!RegMap->isSubRegister(OrigReg)) + mii->getOperand(i).setReg(reg); + else if (MRegisterInfo::isPhysicalRegister(reg)) + mii->getOperand(i).setReg(mri_->getSubReg(reg, + RegMap->getSubRegisterIndex(OrigReg))); // Multiple uses of reg by the same instruction. It should not // contribute to spill weight again. Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=42899&r1=42898&r2=42899&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Fri Oct 12 03:50:34 2007 @@ -242,10 +242,12 @@ /// blocks that have low register pressure (the vreg may be spilled due to /// register pressure in other blocks). class VISIBILITY_HIDDEN LocalSpiller : public Spiller { + SSARegMap *RegMap; const MRegisterInfo *MRI; const TargetInstrInfo *TII; public: bool runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM) { + RegMap = MF.getSSARegMap(); MRI = MF.getTarget().getRegisterInfo(); TII = MF.getTarget().getInstrInfo(); DOUT << "\n**** Local spiller rewriting function '" @@ -776,25 +778,33 @@ if (!MO.isRegister() || MO.getReg() == 0) continue; // Ignore non-register operands. - if (MRegisterInfo::isPhysicalRegister(MO.getReg())) { + unsigned VirtReg = MO.getReg(); + if (MRegisterInfo::isPhysicalRegister(VirtReg)) { // Ignore physregs for spilling, but remember that it is used by this // function. - MF.setPhysRegUsed(MO.getReg()); - ReusedOperands.markClobbered(MO.getReg()); + MF.setPhysRegUsed(VirtReg); + ReusedOperands.markClobbered(VirtReg); continue; } - assert(MRegisterInfo::isVirtualRegister(MO.getReg()) && + assert(MRegisterInfo::isVirtualRegister(VirtReg) && "Not a virtual or a physical register?"); - unsigned VirtReg = MO.getReg(); + unsigned SubIdx = 0; + bool isSubReg = RegMap->isSubRegister(VirtReg); + if (isSubReg) { + SubIdx = RegMap->getSubRegisterIndex(VirtReg); + VirtReg = RegMap->getSuperRegister(VirtReg); + } + if (VRM.isAssignedReg(VirtReg)) { // This virtual register was assigned a physreg! unsigned Phys = VRM.getPhys(VirtReg); MF.setPhysRegUsed(Phys); if (MO.isDef()) ReusedOperands.markClobbered(Phys); - MI.getOperand(i).setReg(Phys); + unsigned RReg = isSubReg ? MRI->getSubReg(Phys, SubIdx) : Phys; + MI.getOperand(i).setReg(RReg); continue; } @@ -817,6 +827,24 @@ if (ReuseSlot != VirtRegMap::NO_STACK_SLOT) PhysReg = Spills.getSpillSlotOrReMatPhysReg(ReuseSlot); } + + // If this is a sub-register use, make sure the reuse register is in the + // right register class. For example, for x86 not all of the 32-bit + // registers have accessible sub-registers. + // Similarly so for EXTRACT_SUBREG. Consider this: + // EDI = op + // MOV32_mr fi#1, EDI + // ... + // = EXTRACT_SUBREG fi#1 + // fi#1 is available in EDI, but it cannot be reused because it's not in + // the right register file. + if (PhysReg && + (isSubReg || MI.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)) { + const TargetRegisterClass* RC = RegMap->getRegClass(VirtReg); + if (!RC->contains(PhysReg)) + PhysReg = 0; + } + if (PhysReg) { // This spilled operand might be part of a two-address operand. If this // is the case, then changing it will necessarily require changing the @@ -824,6 +852,7 @@ // aren't allowed to modify the reused register. If none of these cases // apply, reuse it. bool CanReuse = true; + int ti = TID->getOperandConstraint(i, TOI::TIED_TO); if (ti != -1 && MI.getOperand(ti).isRegister() && @@ -845,7 +874,8 @@ << MRI->getName(PhysReg) << " for vreg" << VirtReg <<" instead of reloading into physreg " << MRI->getName(VRM.getPhys(VirtReg)) << "\n"; - MI.getOperand(i).setReg(PhysReg); + unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg; + MI.getOperand(i).setReg(RReg); // The only technical detail we have is that we don't know that // PhysReg won't be clobbered by a reloaded stack slot that occurs @@ -883,7 +913,7 @@ } } continue; - } + } // CanReuse // Otherwise we have a situation where we have a two-address instruction // whose mod/ref operand needs to be reloaded. This reload is already @@ -917,13 +947,14 @@ DOUT << " from physreg " << MRI->getName(PhysReg) << " for vreg" << VirtReg << " instead of reloading into same physreg.\n"; - MI.getOperand(i).setReg(PhysReg); + unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg; + MI.getOperand(i).setReg(RReg); ReusedOperands.markClobbered(PhysReg); ++NumReused; continue; } - const TargetRegisterClass* RC = MF.getSSARegMap()->getRegClass(VirtReg); + const TargetRegisterClass* RC = RegMap->getRegClass(VirtReg); MF.setPhysRegUsed(DesignatedReg); ReusedOperands.markClobbered(DesignatedReg); MRI->copyRegToReg(MBB, &MI, DesignatedReg, PhysReg, RC, RC); @@ -935,16 +966,17 @@ Spills.ClobberPhysReg(DesignatedReg); Spills.addAvailable(ReuseSlot, &MI, DesignatedReg); - MI.getOperand(i).setReg(DesignatedReg); + unsigned RReg = + isSubReg ? MRI->getSubReg(DesignatedReg, SubIdx) : DesignatedReg; + MI.getOperand(i).setReg(RReg); DOUT << '\t' << *prior(MII); ++NumReused; continue; - } + } // is (PhysReg) // Otherwise, reload it and remember that we have it. PhysReg = VRM.getPhys(VirtReg); assert(PhysReg && "Must map virtreg to physreg!"); - const TargetRegisterClass* RC = MF.getSSARegMap()->getRegClass(VirtReg); // Note that, if we reused a register for a previous operand, the // register we want to reload into might not actually be @@ -960,6 +992,7 @@ MRI->reMaterialize(MBB, &MI, PhysReg, VRM.getReMaterializedMI(VirtReg)); ++NumReMats; } else { + const TargetRegisterClass* RC = RegMap->getRegClass(VirtReg); MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, SSorRMId, RC); ++NumLoads; } @@ -974,7 +1007,8 @@ // unless it's a two-address operand. if (TID->getOperandConstraint(i, TOI::TIED_TO) == -1) MI.getOperand(i).setIsKill(); - MI.getOperand(i).setReg(PhysReg); + unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg; + MI.getOperand(i).setReg(RReg); UpdateKills(*prior(MII), RegKills, KillOps); DOUT << '\t' << *prior(MII); } @@ -1002,30 +1036,28 @@ // straight load from the virt reg slot. if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) { int FrameIdx; - if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) { - if (FrameIdx == SS) { - // If this spill slot is available, turn it into a copy (or nothing) - // instead of leaving it as a load! - if (unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SS)) { - DOUT << "Promoted Load To Copy: " << MI; - if (DestReg != InReg) { - const TargetRegisterClass *RC = - MF.getSSARegMap()->getRegClass(VirtReg); - MRI->copyRegToReg(MBB, &MI, DestReg, InReg, RC, RC); - // Revisit the copy so we make sure to notice the effects of the - // operation on the destreg (either needing to RA it if it's - // virtual or needing to clobber any values if it's physical). - NextMII = &MI; - --NextMII; // backtrack to the copy. - BackTracked = true; - } else - DOUT << "Removing now-noop copy: " << MI; + unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx); + if (DestReg && FrameIdx == SS) { + // If this spill slot is available, turn it into a copy (or nothing) + // instead of leaving it as a load! + if (unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SS)) { + DOUT << "Promoted Load To Copy: " << MI; + if (DestReg != InReg) { + const TargetRegisterClass *RC = RegMap->getRegClass(VirtReg); + MRI->copyRegToReg(MBB, &MI, DestReg, InReg, RC, RC); + // Revisit the copy so we make sure to notice the effects of the + // operation on the destreg (either needing to RA it if it's + // virtual or needing to clobber any values if it's physical). + NextMII = &MI; + --NextMII; // backtrack to the copy. + BackTracked = true; + } else + DOUT << "Removing now-noop copy: " << MI; - VRM.RemoveFromFoldedVirtMap(&MI); - MBB.erase(&MI); - Erased = true; - goto ProcessNextInst; - } + VRM.RemoveFromFoldedVirtMap(&MI); + MBB.erase(&MI); + Erased = true; + goto ProcessNextInst; } } } @@ -1121,7 +1153,7 @@ // The only vregs left are stack slot definitions. int StackSlot = VRM.getStackSlot(VirtReg); - const TargetRegisterClass *RC = MF.getSSARegMap()->getRegClass(VirtReg); + const TargetRegisterClass *RC = RegMap->getRegClass(VirtReg); // If this def is part of a two-address operand, make sure to execute // the store from the correct physical register. From evan.cheng at apple.com Fri Oct 12 04:13:16 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 Oct 2007 09:13:16 -0000 Subject: [llvm-commits] [test-suite] r42902 - /test-suite/trunk/Makefile.programs Message-ID: <200710120913.l9C9DH4f006600@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 04:13:15 2007 New Revision: 42902 URL: http://llvm.org/viewvc/llvm-project?rev=42902&view=rev Log: X86 llcbeta is now -tailcallopt. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=42902&r1=42901&r2=42902&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Fri Oct 12 04:13:15 2007 @@ -221,7 +221,8 @@ LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),x86) -LLCBETAOPTION := -regalloc=local -fast +LLCBETAOPTION := -tailcallopt +#-regalloc=local -fast #-disable-rematerialization #-disable-fp-elim #-regalloc=bigblock -fast From evan.cheng at apple.com Fri Oct 12 04:15:54 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 Oct 2007 09:15:54 -0000 Subject: [llvm-commits] [llvm] r42903 - /llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Message-ID: <200710120915.l9C9Ft06006665@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 04:15:53 2007 New Revision: 42903 URL: http://llvm.org/viewvc/llvm-project?rev=42903&view=rev Log: Restrict EXTRACT_SUBREG coalescing to avoid negative performance impact. Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=42903&r1=42902&r2=42903&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Fri Oct 12 04:15:53 2007 @@ -264,8 +264,13 @@ if (li_->hasInterval(*SR) && RHS.overlaps(li_->getInterval(*SR))) { DOUT << "Interfere with sub-register "; DEBUG(li_->getInterval(*SR).print(DOUT, mri_)); - return true; + return true; // Not coalescable } + } else if (li_->getInterval(repDstReg).getSize() > + li_->getInterval(repSrcReg).getSize()) { + // Be conservative. If both sides are virtual registers, do not coalesce + // if the sub-register live interval is longer. + return false; } } else if (differingRegisterClasses(repSrcReg, repDstReg)) { // If they are not of the same register class, we cannot join them. From evan.cheng at apple.com Fri Oct 12 04:10:28 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 Oct 2007 09:10:28 -0000 Subject: [llvm-commits] [llvm] r42901 - /llvm/trunk/test/CodeGen/X86/2007-10-12-CoalesceExtSubReg.ll Message-ID: <200710120910.l9C9ASQF006532@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 04:10:27 2007 New Revision: 42901 URL: http://llvm.org/viewvc/llvm-project?rev=42901&view=rev Log: Doh. Modified: llvm/trunk/test/CodeGen/X86/2007-10-12-CoalesceExtSubReg.ll Modified: llvm/trunk/test/CodeGen/X86/2007-10-12-CoalesceExtSubReg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-10-12-CoalesceExtSubReg.ll?rev=42901&r1=42900&r2=42901&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-10-12-CoalesceExtSubReg.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-10-12-CoalesceExtSubReg.ll Fri Oct 12 04:10:27 2007 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 | not movb +; RUN: llvm-as < %s | llc -march=x86 | not grep movb define i16 @f(i32* %bp, i32* %ss) signext { entry: From evan.cheng at apple.com Fri Oct 12 04:03:34 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 Oct 2007 09:03:34 -0000 Subject: [llvm-commits] [llvm] r42900 - /llvm/trunk/test/CodeGen/X86/2007-10-12-CoalesceExtSubReg.ll Message-ID: <200710120903.l9C93Z2X006275@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 04:03:31 2007 New Revision: 42900 URL: http://llvm.org/viewvc/llvm-project?rev=42900&view=rev Log: EXTRACT_SUBREG test case. Added: llvm/trunk/test/CodeGen/X86/2007-10-12-CoalesceExtSubReg.ll Added: llvm/trunk/test/CodeGen/X86/2007-10-12-CoalesceExtSubReg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-10-12-CoalesceExtSubReg.ll?rev=42900&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-10-12-CoalesceExtSubReg.ll (added) +++ llvm/trunk/test/CodeGen/X86/2007-10-12-CoalesceExtSubReg.ll Fri Oct 12 04:03:31 2007 @@ -0,0 +1,35 @@ +; RUN: llvm-as < %s | llc -march=x86 | not movb + +define i16 @f(i32* %bp, i32* %ss) signext { +entry: + br label %cond_next127 + +cond_next127: ; preds = %cond_next391, %entry + %v.1 = phi i32 [ undef, %entry ], [ %tmp411, %cond_next391 ] ; [#uses=1] + %tmp149 = mul i32 0, %v.1 ; [#uses=0] + %tmp254 = and i32 0, 15 ; [#uses=1] + %tmp256 = and i32 0, 15 ; [#uses=2] + br i1 false, label %cond_true267, label %cond_next391 + +cond_true267: ; preds = %cond_next127 + ret i16 0 + +cond_next391: ; preds = %cond_next127 + %tmp393 = load i32* %ss, align 4 ; [#uses=1] + %tmp395 = load i32* %bp, align 4 ; [#uses=2] + %tmp396 = shl i32 %tmp393, %tmp395 ; [#uses=2] + %tmp398 = sub i32 32, %tmp256 ; [#uses=2] + %tmp399 = lshr i32 %tmp396, %tmp398 ; [#uses=1] + %tmp405 = lshr i32 %tmp396, 31 ; [#uses=1] + %tmp406 = add i32 %tmp405, -1 ; [#uses=1] + %tmp409 = lshr i32 %tmp406, %tmp398 ; [#uses=1] + %tmp411 = sub i32 %tmp399, %tmp409 ; [#uses=1] + %tmp422445 = add i32 %tmp254, 0 ; [#uses=1] + %tmp426447 = add i32 %tmp395, %tmp256 ; [#uses=1] + store i32 %tmp426447, i32* %bp, align 4 + %tmp429448 = icmp ult i32 %tmp422445, 63 ; [#uses=1] + br i1 %tmp429448, label %cond_next127, label %UnifiedReturnBlock + +UnifiedReturnBlock: ; preds = %cond_next391 + ret i16 0 +} From djg at cray.com Fri Oct 12 09:08:58 2007 From: djg at cray.com (Dan Gohman) Date: Fri, 12 Oct 2007 14:08:58 -0000 Subject: [llvm-commits] [llvm] r42904 - /llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200710121408.l9CE8wSe015165@zion.cs.uiuc.edu> Author: djg Date: Fri Oct 12 09:08:57 2007 New Revision: 42904 URL: http://llvm.org/viewvc/llvm-project?rev=42904&view=rev Log: Mark vector pow, ctpop, cttz, and ctlz as Expand on PowerPC. Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=42904&r1=42903&r2=42904&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Fri Oct 12 09:08:57 2007 @@ -284,8 +284,11 @@ setOperationAction(ISD::SMUL_LOHI, (MVT::ValueType)VT, Expand); setOperationAction(ISD::UDIVREM, (MVT::ValueType)VT, Expand); setOperationAction(ISD::SDIVREM, (MVT::ValueType)VT, Expand); - setOperationAction(ISD::SCALAR_TO_VECTOR, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::FPOW, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::CTPOP, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::CTLZ, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::CTTZ, (MVT::ValueType)VT, Expand); } // We can custom expand all VECTOR_SHUFFLEs to VPERM, others we can handle From djg at cray.com Fri Oct 12 09:09:42 2007 From: djg at cray.com (Dan Gohman) Date: Fri, 12 Oct 2007 14:09:42 -0000 Subject: [llvm-commits] [llvm] r42905 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200710121409.l9CE9gIt015221@zion.cs.uiuc.edu> Author: djg Date: Fri Oct 12 09:09:42 2007 New Revision: 42905 URL: http://llvm.org/viewvc/llvm-project?rev=42905&view=rev Log: Mark vector ctpop, cttz, and ctlz as Expand on x86. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=42905&r1=42904&r2=42905&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Oct 12 09:09:42 2007 @@ -477,6 +477,9 @@ setOperationAction(ISD::SDIVREM, (MVT::ValueType)VT, Expand); setOperationAction(ISD::UDIVREM, (MVT::ValueType)VT, Expand); setOperationAction(ISD::FPOW, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::CTPOP, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::CTTZ, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::CTLZ, (MVT::ValueType)VT, Expand); } if (Subtarget->hasMMX()) { From djg at cray.com Fri Oct 12 09:13:46 2007 From: djg at cray.com (Dan Gohman) Date: Fri, 12 Oct 2007 14:13:46 -0000 Subject: [llvm-commits] [llvm] r42906 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200710121413.l9CEDkxP015390@zion.cs.uiuc.edu> Author: djg Date: Fri Oct 12 09:13:46 2007 New Revision: 42906 URL: http://llvm.org/viewvc/llvm-project?rev=42906&view=rev Log: Add support to SplitVectorOp for powi, where the second operand is a scalar integer. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=42906&r1=42905&r2=42906&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Oct 12 09:13:46 2007 @@ -6335,6 +6335,12 @@ NewVT, ScalarizeVectorOp(Node->getOperand(0))); break; + case ISD::FPOWI: + Result = DAG.getNode(Node->getOpcode(), + NewVT, + ScalarizeVectorOp(Node->getOperand(0)), + Node->getOperand(1)); + break; case ISD::LOAD: { LoadSDNode *LD = cast(Node); SDOperand Ch = LegalizeOp(LD->getChain()); // Legalize the chain. From djg at cray.com Fri Oct 12 09:33:11 2007 From: djg at cray.com (Dan Gohman) Date: Fri, 12 Oct 2007 14:33:11 -0000 Subject: [llvm-commits] [llvm] r42907 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200710121433.l9CEXBWX016083@zion.cs.uiuc.edu> Author: djg Date: Fri Oct 12 09:33:11 2007 New Revision: 42907 URL: http://llvm.org/viewvc/llvm-project?rev=42907&view=rev Log: Fix some corner cases with vectors in copyToRegs and copyFromRegs. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=42907&r1=42906&r2=42907&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Oct 12 09:33:11 2007 @@ -648,7 +648,15 @@ if (MVT::isVector(PartVT)) { assert(MVT::isVector(ValueVT) && "Unknown vector conversion!"); - return DAG.getNode(ISD::BIT_CONVERT, PartVT, Val); + return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val); + } + + if (MVT::isVector(ValueVT)) { + assert(NumParts == 1 && + MVT::getVectorElementType(ValueVT) == PartVT && + MVT::getVectorNumElements(ValueVT) == 1 && + "Only trivial scalar-to-vector conversions should get here!"); + return DAG.getNode(ISD::BUILD_VECTOR, ValueVT, Val); } if (MVT::isInteger(PartVT) && @@ -746,6 +754,13 @@ assert(MVT::isVector(ValueVT) && "Not a vector-vector cast?"); Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val); + } else if (MVT::isVector(ValueVT)) { + assert(NumParts == 1 && + MVT::getVectorElementType(ValueVT) == PartVT && + MVT::getVectorNumElements(ValueVT) == 1 && + "Only trivial vector-to-scalar conversions should get here!"); + Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, PartVT, Val, + DAG.getConstant(0, PtrVT)); } else if (MVT::isInteger(PartVT) && MVT::isInteger(ValueVT)) { if (PartVT < ValueVT) Val = DAG.getNode(ISD::TRUNCATE, PartVT, Val); From djg at cray.com Fri Oct 12 09:53:36 2007 From: djg at cray.com (Dan Gohman) Date: Fri, 12 Oct 2007 14:53:36 -0000 Subject: [llvm-commits] [llvm] r42908 - in /llvm/trunk: include/llvm/CodeGen/ lib/CodeGen/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/X86/ test/CodeGen/X86/ Message-ID: <200710121453.l9CEraSq016799@zion.cs.uiuc.edu> Author: djg Date: Fri Oct 12 09:53:36 2007 New Revision: 42908 URL: http://llvm.org/viewvc/llvm-project?rev=42908&view=rev Log: Change the names used for internal labels to use the current function symbol name instead of a codegen-assigned function number. Thanks Evan! :-) Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h llvm/trunk/lib/CodeGen/AsmPrinter.cpp llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp llvm/trunk/test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll llvm/trunk/test/CodeGen/X86/fp_constant_op.llx Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AsmPrinter.h?rev=42908&r1=42907&r2=42908&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original) +++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Fri Oct 12 09:53:36 2007 @@ -36,13 +36,6 @@ class AsmPrinter : public MachineFunctionPass { static char ID; - /// FunctionNumber - This provides a unique ID for each function emitted in - /// this translation unit. It is autoincremented by SetupMachineFunction, - /// and can be accessed with getFunctionNumber() and - /// IncrementFunctionNumber(). - /// - unsigned FunctionNumber; - protected: // Necessary for external weak linkage support std::set ExtWeakSymbols; @@ -160,15 +153,6 @@ /// is being processed from runOnMachineFunction. void SetupMachineFunction(MachineFunction &MF); - /// getFunctionNumber - Return a unique ID for the current function. - /// - unsigned getFunctionNumber() const { return FunctionNumber; } - - /// IncrementFunctionNumber - Increase Function Number. AsmPrinters should - /// not normally call this, as the counter is automatically bumped by - /// SetupMachineFunction. - void IncrementFunctionNumber() { FunctionNumber++; } - /// EmitConstantPool - Print to the current output stream assembly /// representations of the constants in the constant pool MCP. This is /// used to print out constants which have been "spilled to memory" by Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Fri Oct 12 09:53:36 2007 @@ -35,7 +35,7 @@ char AsmPrinter::ID = 0; AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm, const TargetAsmInfo *T) - : MachineFunctionPass((intptr_t)&ID), FunctionNumber(0), O(o), TM(tm), TAI(T) + : MachineFunctionPass((intptr_t)&ID), O(o), TM(tm), TAI(T) {} std::string AsmPrinter::getSectionForFunction(const Function &F) const { @@ -169,7 +169,6 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { // What's my mangled name? CurrentFnName = Mang->getValueName(MF.getFunction()); - IncrementFunctionNumber(); } /// EmitConstantPool - Print to the current output stream assembly @@ -219,8 +218,9 @@ SwitchToDataSection(Section); EmitAlignment(Alignment); for (unsigned i = 0, e = CP.size(); i != e; ++i) { - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' - << CP[i].second << ":\t\t\t\t\t" << TAI->getCommentString() << " "; + O << TAI->getPrivateGlobalPrefix() << "CPI" << CP[i].second + << '_' << CurrentFnName + << ":\t\t\t\t\t" << TAI->getCommentString() << ' '; WriteTypeSymbolic(O, CP[i].first.getType(), 0) << '\n'; if (CP[i].first.isMachineConstantPoolEntry()) EmitMachineConstantPoolValue(CP[i].first.Val.MachineCPVal); @@ -293,10 +293,10 @@ // the assembler and linker the extents of the jump table object. The // second label is actually referenced by the code. if (const char *JTLabelPrefix = TAI->getJumpTableSpecialLabelPrefix()) - O << JTLabelPrefix << "JTI" << getFunctionNumber() << '_' << i << ":\n"; + O << JTLabelPrefix << "JTI" << i << '_' << CurrentFnName << ":\n"; - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << i << ":\n"; + O << TAI->getPrivateGlobalPrefix() << "JTI" << i + << '_' << CurrentFnName << ":\n"; for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { O << JTEntryDirective << ' '; @@ -306,15 +306,15 @@ // If we're emitting non-PIC code, then emit the entries as direct // references to the target basic blocks. if (!EmittedSets.empty()) { - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << '_' << i << "_set_" << JTBBs[ii]->getNumber(); + O << TAI->getPrivateGlobalPrefix() << i + << '_' << "_set_" << JTBBs[ii]->getNumber() << '_' << CurrentFnName; } else if (IsPic) { printBasicBlockLabel(JTBBs[ii], false, false); // If the arch uses custom Jump Table directives, don't calc relative to // JT if (!HadJTEntryDirective) O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" - << getFunctionNumber() << '_' << i; + << i << '_' << CurrentFnName; } else { printBasicBlockLabel(JTBBs[ii], false, false); } @@ -1242,8 +1242,8 @@ void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB, bool printColon, bool printComment) const { - O << TAI->getPrivateGlobalPrefix() << "BB" << getFunctionNumber() << "_" - << MBB->getNumber(); + O << TAI->getPrivateGlobalPrefix() << "BB" << MBB->getNumber() << '_' + << CurrentFnName; if (printColon) O << ':'; if (printComment && MBB->getBasicBlock()) @@ -1259,10 +1259,10 @@ return; O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() - << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','; + << uid << "_set_" << MBB->getNumber() << '_' << CurrentFnName << ','; printBasicBlockLabel(MBB, false, false); - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << uid << '\n'; + O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << uid + << '_' << CurrentFnName << '\n'; } void AsmPrinter::printSetLabel(unsigned uid, unsigned uid2, @@ -1271,11 +1271,11 @@ return; O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() - << getFunctionNumber() << '_' << uid << '_' << uid2 - << "_set_" << MBB->getNumber() << ','; + << uid << '_' << uid2 + << "_set_" << MBB->getNumber() << '_' << CurrentFnName << ','; printBasicBlockLabel(MBB, false, false); - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << uid << '_' << uid2 << '\n'; + O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << uid + << '_' << uid2 << '_' << CurrentFnName << '\n'; } /// printDataDirective - This method prints the asm directive for the Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Fri Oct 12 09:53:36 2007 @@ -319,12 +319,12 @@ break; } case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() - << '_' << MO.getConstantPoolIndex(); + O << TAI->getPrivateGlobalPrefix() << "CPI" << MO.getConstantPoolIndex() + << '_' << CurrentFnName; break; case MachineOperand::MO_JumpTableIndex: - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << MO.getJumpTableIndex(); + O << TAI->getPrivateGlobalPrefix() << "JTI" << MO.getJumpTableIndex() + << '_' << CurrentFnName; break; default: O << ""; abort (); break; @@ -652,8 +652,8 @@ // data itself. if (!strcmp(Modifier, "label")) { unsigned ID = MI->getOperand(OpNo).getImm(); - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() - << '_' << ID << ":\n"; + O << TAI->getPrivateGlobalPrefix() << "CPI" << ID + << '_' << CurrentFnName << ":\n"; } else { assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE"); unsigned CPI = MI->getOperand(OpNo).getConstantPoolIndex(); @@ -677,8 +677,8 @@ const MachineOperand &MO1 = MI->getOperand(OpNo); const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id unsigned JTI = MO1.getJumpTableIndex(); - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << JTI << '_' << MO2.getImmedValue() << ":\n"; + O << TAI->getPrivateGlobalPrefix() << "JTI" << JTI + << '_' << MO2.getImmedValue() << '_' << CurrentFnName << ":\n"; const char *JTEntryDirective = TAI->getJumpTableDirective(); if (!JTEntryDirective) @@ -697,15 +697,16 @@ O << JTEntryDirective << ' '; if (UseSet) - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << '_' << JTI << '_' << MO2.getImmedValue() - << "_set_" << MBB->getNumber(); + O << TAI->getPrivateGlobalPrefix() << JTI + << '_' << MO2.getImmedValue() + << "_set_" << MBB->getNumber() + << CurrentFnName; else if (TM.getRelocationModel() == Reloc::PIC_) { printBasicBlockLabel(MBB, false, false); // If the arch uses custom Jump Table directives, don't calc relative to JT if (!TAI->getJumpTableDirective()) O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" - << getFunctionNumber() << '_' << JTI << '_' << MO2.getImmedValue(); + << JTI << '_' << MO2.getImmedValue() << '_' << CurrentFnName; } else printBasicBlockLabel(MBB, false, false); if (i != e-1) Modified: llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp Fri Oct 12 09:53:36 2007 @@ -104,8 +104,8 @@ return; case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" - << MO.getConstantPoolIndex(); + O << TAI->getPrivateGlobalPrefix() << "CPI" << MO.getConstantPoolIndex() + << '_' << CurrentFnName; return; case MachineOperand::MO_ExternalSymbol: @@ -121,8 +121,8 @@ } case MachineOperand::MO_JumpTableIndex: - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << MO.getJumpTableIndex(); + O << TAI->getPrivateGlobalPrefix() << "JTI" << MO.getJumpTableIndex() + << '_' << CurrentFnName; return; default: Modified: llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff ============================================================================== --- llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp Fri Oct 12 09:53:36 2007 @@ -179,8 +179,8 @@ return; case MachineOperand::MO_ConstantPoolIndex: { O << "@gprel(" << TAI->getPrivateGlobalPrefix() - << "CPI" << getFunctionNumber() << "_" - << MO.getConstantPoolIndex() << ")"; + << "CPI" << MO.getConstantPoolIndex() << '_' + << CurrentFnName << ")"; return; } Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Fri Oct 12 09:53:36 2007 @@ -363,7 +363,7 @@ case MachineOperand::MO_ConstantPoolIndex: O << TAI->getPrivateGlobalPrefix() << "CPI" - << getFunctionNumber() << "_" << MO.getConstantPoolIndex(); + << MO.getConstantPoolIndex() << '_' << CurrentFnName; break; default: Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Fri Oct 12 09:53:36 2007 @@ -164,7 +164,7 @@ O << "lo16("; printOp(MI->getOperand(OpNo)); if (TM.getRelocationModel() == Reloc::PIC_) - O << "-\"L" << getFunctionNumber() << "$pb\")"; + O << "-\"L" "pb$" << CurrentFnName << "\")"; else O << ')'; } @@ -208,8 +208,8 @@ O << (int)MI->getOperand(OpNo).getImmedValue()*4; } void printPICLabel(const MachineInstr *MI, unsigned OpNo) { - O << "\"L" << getFunctionNumber() << "$pb\"\n"; - O << "\"L" << getFunctionNumber() << "$pb\":"; + O << "\"L" "pb$" << CurrentFnName << "\"\n"; + O << "\"L" "pb$" << CurrentFnName << "\":"; } void printSymbolHi(const MachineInstr *MI, unsigned OpNo) { if (MI->getOperand(OpNo).isImmediate()) { @@ -218,7 +218,7 @@ if (Subtarget.isDarwin()) O << "ha16("; printOp(MI->getOperand(OpNo)); if (TM.getRelocationModel() == Reloc::PIC_) - O << "-\"L" << getFunctionNumber() << "$pb\""; + O << "-\"L" "pb$" << CurrentFnName << "\""; if (Subtarget.isDarwin()) O << ')'; else @@ -232,7 +232,7 @@ if (Subtarget.isDarwin()) O << "lo16("; printOp(MI->getOperand(OpNo)); if (TM.getRelocationModel() == Reloc::PIC_) - O << "-\"L" << getFunctionNumber() << "$pb\""; + O << "-\"L" "pb$" << CurrentFnName << "\""; if (Subtarget.isDarwin()) O << ')'; else @@ -362,13 +362,13 @@ printBasicBlockLabel(MO.getMachineBasicBlock()); return; case MachineOperand::MO_JumpTableIndex: - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << MO.getJumpTableIndex(); + O << TAI->getPrivateGlobalPrefix() << "JTI" << MO.getJumpTableIndex() + << '_' << CurrentFnName; // FIXME: PIC relocation model return; case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() - << '_' << MO.getConstantPoolIndex(); + O << TAI->getPrivateGlobalPrefix() << "CPI" << MO.getConstantPoolIndex() + << '_' << CurrentFnName; return; case MachineOperand::MO_ExternalSymbol: // Computing the address of an external symbol, not calling it. Modified: llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp Fri Oct 12 09:53:36 2007 @@ -164,8 +164,8 @@ O << MO.getSymbolName(); break; case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" - << MO.getConstantPoolIndex(); + O << TAI->getPrivateGlobalPrefix() << "CPI" << MO.getConstantPoolIndex() + << '_' << CurrentFnName; break; default: O << ""; abort (); break; Modified: llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp Fri Oct 12 09:53:36 2007 @@ -31,14 +31,14 @@ STATISTIC(EmittedInsts, "Number of machine instrs printed"); -static std::string computePICLabel(unsigned FnNum, +static std::string computePICLabel(const std::string &FnName, const TargetAsmInfo *TAI, const X86Subtarget* Subtarget) { std::string label; if (Subtarget->isTargetDarwin()) - label = "\"L" + utostr_32(FnNum) + "$pb\""; + label = "\"L" "pb$" + FnName + "\""; else if (Subtarget->isTargetELF()) - label = ".Lllvm$" + utostr_32(FnNum) + "$piclabel"; + label = ".Lllvm$piclabel$" + FnName; else assert(0 && "Don't know how to print PIC label!\n"); @@ -236,13 +236,13 @@ case MachineOperand::MO_JumpTableIndex: { bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp) O << '$'; - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << "_" - << MO.getJumpTableIndex(); + O << TAI->getPrivateGlobalPrefix() << "JTI" << MO.getJumpTableIndex() + << '_' << CurrentFnName; if (TM.getRelocationModel() == Reloc::PIC_) { if (Subtarget->isPICStyleStub()) - O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << "$pb\""; + O << "-\"" << TAI->getPrivateGlobalPrefix() << "pb$" << CurrentFnName + << "\""; else if (Subtarget->isPICStyleGOT()) O << "@GOTOFF"; } @@ -254,13 +254,13 @@ case MachineOperand::MO_ConstantPoolIndex: { bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp) O << '$'; - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" - << MO.getConstantPoolIndex(); + O << TAI->getPrivateGlobalPrefix() << "CPI" << MO.getConstantPoolIndex() + << '_' << CurrentFnName; if (TM.getRelocationModel() == Reloc::PIC_) { if (Subtarget->isPICStyleStub()) - O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << "$pb\""; + O << "-\"" << TAI->getPrivateGlobalPrefix() << "pb$" << CurrentFnName + << "\""; else if (Subtarget->isPICStyleGOT()) O << "@GOTOFF"; } @@ -317,8 +317,8 @@ } if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_) - O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << "$pb\""; + O << "-\"" << TAI->getPrivateGlobalPrefix() << "pb$" << CurrentFnName + << "\""; } else { if (GV->hasDLLImportLinkage()) { O << "__imp_"; @@ -418,7 +418,7 @@ // popl %some_register // addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register O << " + [.-" - << computePICLabel(getFunctionNumber(), TAI, Subtarget) << "]"; + << computePICLabel(CurrentFnName, TAI, Subtarget) << "]"; if (isCallOp) O << "@PLT"; @@ -498,7 +498,7 @@ } void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { - std::string label = computePICLabel(getFunctionNumber(), TAI, Subtarget); + std::string label = computePICLabel(CurrentFnName, TAI, Subtarget); O << label << "\n" << label << ":"; } Modified: llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp Fri Oct 12 09:53:36 2007 @@ -140,15 +140,15 @@ case MachineOperand::MO_JumpTableIndex: { bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp) O << "OFFSET "; - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << "_" << MO.getJumpTableIndex(); + O << TAI->getPrivateGlobalPrefix() << "JTI" << MO.getJumpTableIndex() + << '_' << CurrentFnName; return; } case MachineOperand::MO_ConstantPoolIndex: { bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp) O << "OFFSET "; O << "[" << TAI->getPrivateGlobalPrefix() << "CPI" - << getFunctionNumber() << "_" << MO.getConstantPoolIndex(); + << MO.getConstantPoolIndex() << '_' << CurrentFnName; int Offset = MO.getOffset(); if (Offset > 0) O << " + " << Offset; @@ -236,8 +236,8 @@ } void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { - O << "\"L" << getFunctionNumber() << "$pb\"\n"; - O << "\"L" << getFunctionNumber() << "$pb\":"; + O << "\"L" "pb$" << CurrentFnName << "\"\n"; + O << "\"L" "pb$" << CurrentFnName << "\":"; } bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand &MO, Modified: llvm/trunk/test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll?rev=42908&r1=42907&r2=42908&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll (original) +++ llvm/trunk/test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll Fri Oct 12 09:53:36 2007 @@ -1,5 +1,5 @@ ; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86 | %prcontext je 1 | \ -; RUN: grep BB1_1: +; RUN: grep BB1_main: %str = internal constant [14 x sbyte] c"Hello world!\0A\00" ; <[14 x sbyte]*> [#uses=1] %str = internal constant [13 x sbyte] c"Blah world!\0A\00" ; <[13 x sbyte]*> [#uses=1] Modified: llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll?rev=42908&r1=42907&r2=42908&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll Fri Oct 12 09:53:36 2007 @@ -1,6 +1,6 @@ ; PR1075 ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | \ -; RUN: %prcontext {mulss LCPI1_3} 1 | grep mulss | count 1 +; RUN: %prcontext {mulss LCPI3__foo} 1 | grep mulss | count 1 define float @foo(float %x) { %tmp1 = mul float %x, 3.000000e+00 Modified: llvm/trunk/test/CodeGen/X86/fp_constant_op.llx URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fp_constant_op.llx?rev=42908&r1=42907&r2=42908&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/fp_constant_op.llx (original) +++ llvm/trunk/test/CodeGen/X86/fp_constant_op.llx Fri Oct 12 09:53:36 2007 @@ -3,32 +3,32 @@ ; Test that the load of the constant is folded into the operation. -double %test_add(double %P) { +double %foo_add(double %P) { %tmp.1 = add double %P, 0x405EC00000000000 ret double %tmp.1 } -double %test_mul(double %P) { +double %foo_mul(double %P) { %tmp.1 = mul double %P, 0x405EC00000000000 ret double %tmp.1 } -double %test_sub(double %P) { +double %foo_sub(double %P) { %tmp.1 = sub double %P, 0x405EC00000000000 ret double %tmp.1 } -double %test_subr(double %P) { +double %foo_subr(double %P) { %tmp.1 = sub double 0x405EC00000000000, %P ret double %tmp.1 } -double %test_div(double %P) { +double %foo_div(double %P) { %tmp.1 = div double %P, 0x405EC00000000000 ret double %tmp.1 } -double %test_divr(double %P) { +double %foo_divr(double %P) { %tmp.1 = div double 0x405EC00000000000, %P ret double %tmp.1 } From baldrick at free.fr Fri Oct 12 09:56:17 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 12 Oct 2007 16:56:17 +0200 Subject: [llvm-commits] [llvm] r42870 - in /llvm/trunk: include/llvm/Target/ lib/CodeGen/SelectionDAG/ lib/Target/ lib/Target/X86/ test/CodeGen/X86/ In-Reply-To: <200710111940.l9BJeCqc031930@zion.cs.uiuc.edu> References: <200710111940.l9BJeCqc031930@zion.cs.uiuc.edu> Message-ID: <200710121656.18457.baldrick@free.fr> Hi Arnold, > + /// tail call optimization. Target which want to do tail call optimization > + /// should implement this function. Target -> Targets. Also shouldn't it be "override" rather than "implement"? > + /// PerformTailCallOpt - This flag is enabled when the -tailcallopt is when the -> when > +/// CheckDAGForTailCallsAndFixThem - This Function looks for CALL nodes in the > +/// DAG and fixes their tailcall attribute operand Missing full stop at the end. > +pushes all arguments on the top of the stack (their normal place if > +that was a not tail call optimized functiong call ) before moving them if that was a not tail call optimized functiong call -> for non-tail call optimized calls > +to actual stack slot. this is done to prevent overwriting of paramters this -> This paramters -> parameters > +callee overwrites callers arguments. callers -> the caller's > + parameters of the caller function and have no local value in the > + caller Missing full stop. > + in above example local does not need to be pushed onto the top of in above -> In the above > + the stack as it is definitetly not a caller's function parameter definitetly -> definitely Missing full stop. > + overwrite a caller paramter which is used by the callee and only paramter -> parameter > + push them onto the top of the stack Missing full stop. > + here we don't need to write any variables to the top of the stack here -> Here > + since they don't overwrite each other Missing full stop. > + here we need to push the arguments because they overwrite each other here -> Here Missing full stop. > + code for lowering directly onto callers arguments: code -> Code > +// tail call convetion (fast) one register is reserved for target address > +// namely R9 tail -> Tail convetion -> convention (fast) one -> (fast): One address namely R9 -> address, namely R9. > +/// Same as C calling convention up to nonfree ECX which is used for storing > +/// potential pointer to tail called function up to nonfree -> except for non-free storing potential -> storing a potential Missing full stop. Note that ECX may be used if there is a 'nest' parameter, see this line: + // The 'nest' parameter, if any, is passed in ECX. + CCIfNest>, How do you avoid collisions? Ciao, Duncan. From arnold.schwaighofer at gmail.com Fri Oct 12 10:21:31 2007 From: arnold.schwaighofer at gmail.com (Arnold Schwaighofer) Date: Fri, 12 Oct 2007 17:21:31 +0200 Subject: [llvm-commits] [llvm] r42870 - in /llvm/trunk: include/llvm/Target/ lib/CodeGen/SelectionDAG/ lib/Target/ lib/Target/X86/ test/CodeGen/X86/ In-Reply-To: <200710121656.18457.baldrick@free.fr> References: <200710111940.l9BJeCqc031930@zion.cs.uiuc.edu> <200710121656.18457.baldrick@free.fr> Message-ID: On 10/12/07, Duncan Sands wrote: > ... many comment corrections Will correct them. > Note that ECX may be used if there is a 'nest' parameter, see this line: > + // The 'nest' parameter, if any, is passed in ECX. > + CCIfNest>, > > How do you avoid collisions? I don't. A copy paste error. But if i understand correctly the CC_X86_32_C calling convention does not prevent collisions either. def CC_X86_32_C : CallingConv<[ // Promote i8/i16 arguments to i32. CCIfType<[i8, i16], CCPromoteToType>, // The 'nest' parameter, if any, is passed in ECX. CCIfNest>, // The first 3 integer arguments, if marked 'inreg' and if the call is not // a vararg call, are passed in integer registers. CCIfNotVarArg>>>, I would propose that tail call optimized fastcc functions do not support nested functions. The other possiblity would be to reserve a register for the nest parameter but then there is only one register left for argument passing. EAX used for nesting. ECX used for possible function pointer to be called. EDX (only register that can than be) used for inreg argument passing. > Ciao, > > > Duncan. > regards From neil at daikokuya.co.uk Fri Oct 12 10:31:31 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Fri, 12 Oct 2007 15:31:31 -0000 Subject: [llvm-commits] [llvm] r42909 - /llvm/trunk/lib/Support/APInt.cpp Message-ID: <200710121531.l9CFVWh2017817@zion.cs.uiuc.edu> Author: neil Date: Fri Oct 12 10:31:31 2007 New Revision: 42909 URL: http://llvm.org/viewvc/llvm-project?rev=42909&view=rev Log: Don't attempt to mask no bits Modified: llvm/trunk/lib/Support/APInt.cpp Modified: llvm/trunk/lib/Support/APInt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=42909&r1=42908&r2=42909&view=diff ============================================================================== --- llvm/trunk/lib/Support/APInt.cpp (original) +++ llvm/trunk/lib/Support/APInt.cpp Fri Oct 12 10:31:31 2007 @@ -2212,7 +2212,8 @@ dst[dstParts - 1] |= ((src[firstSrcPart + dstParts] & mask) << n % integerPartWidth); } else if (n > srcBits) { - dst[dstParts - 1] &= lowBitMask (srcBits % integerPartWidth); + if (srcBits % integerPartWidth) + dst[dstParts - 1] &= lowBitMask (srcBits % integerPartWidth); } /* Clear high parts. */ From neil at daikokuya.co.uk Fri Oct 12 10:33:27 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Fri, 12 Oct 2007 15:33:27 -0000 Subject: [llvm-commits] [llvm] r42910 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200710121533.l9CFXRn7017875@zion.cs.uiuc.edu> Author: neil Date: Fri Oct 12 10:33:27 2007 New Revision: 42910 URL: http://llvm.org/viewvc/llvm-project?rev=42910&view=rev Log: If we're trying to be arbitrary precision, unsigned char clearly won't cut it. Needed for dec->bin conversions. Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=42910&r1=42909&r2=42910&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Fri Oct 12 10:33:27 2007 @@ -39,7 +39,7 @@ /* Number of bits in the significand. This includes the integer bit. */ - unsigned char precision; + unsigned int precision; /* If the target format has an implicit integer bit. */ bool implicitIntegerBit; From neil at daikokuya.co.uk Fri Oct 12 10:35:10 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Fri, 12 Oct 2007 15:35:10 -0000 Subject: [llvm-commits] [llvm] r42911 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200710121535.l9CFZAhY017939@zion.cs.uiuc.edu> Author: neil Date: Fri Oct 12 10:35:10 2007 New Revision: 42911 URL: http://llvm.org/viewvc/llvm-project?rev=42911&view=rev Log: Remove a field that was never used. Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=42911&r1=42910&r2=42911&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Fri Oct 12 10:35:10 2007 @@ -40,21 +40,18 @@ /* Number of bits in the significand. This includes the integer bit. */ unsigned int precision; - - /* If the target format has an implicit integer bit. */ - bool implicitIntegerBit; }; - const fltSemantics APFloat::IEEEsingle = { 127, -126, 24, true }; - const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53, true }; - const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, true }; - const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64, false }; - const fltSemantics APFloat::Bogus = { 0, 0, 0, false }; + const fltSemantics APFloat::IEEEsingle = { 127, -126, 24 }; + const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53 }; + const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113 }; + const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64 }; + const fltSemantics APFloat::Bogus = { 0, 0, 0 }; // The PowerPC format consists of two doubles. It does not map cleanly // onto the usual format above. For now only storage of constants of // this type is supported, no arithmetic. - const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022, 106, true }; + const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022, 106 }; } /* Put a bunch of private, handy routines in an anonymous namespace. */ From neil at daikokuya.co.uk Fri Oct 12 11:02:31 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Fri, 12 Oct 2007 16:02:31 -0000 Subject: [llvm-commits] [llvm] r42912 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/Support/APFloat.cpp Message-ID: <200710121602.l9CG2VWR019008@zion.cs.uiuc.edu> Author: neil Date: Fri Oct 12 11:02:31 2007 New Revision: 42912 URL: http://llvm.org/viewvc/llvm-project?rev=42912&view=rev Log: Implement correctly-rounded decimal->binary conversion, i.e. conversion from user input strings. Such conversions are more intricate and subtle than they may appear; it is unlikely I have got it completely right first time. I would appreciate being informed of any bugs and incorrect roundings you might discover. Modified: llvm/trunk/include/llvm/ADT/APFloat.h llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=42912&r1=42911&r2=42912&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (original) +++ llvm/trunk/include/llvm/ADT/APFloat.h Fri Oct 12 11:02:31 2007 @@ -60,7 +60,10 @@ if the requested precision is less than the natural precision the output is correctly rounded for the specified rounding mode. - Conversion to and from decimal text is not currently implemented. + It also reads decimal floating point numbers and correctly rounds + according to the specified rounding mode. + + Conversion to decimal text is not currently implemented. Non-zero finite numbers are represented internally as a sign bit, a 16-bit signed exponent, and the significand as an array of @@ -83,13 +86,12 @@ Some features that may or may not be worth adding: - Conversions to and from decimal strings (hard). + Binary to decimal conversion (hard). Optional ability to detect underflow tininess before rounding. New formats: x87 in single and double precision mode (IEEE apart - from extended exponent range) and IBM two-double extended - precision (hard). + from extended exponent range) (hard). New operations: sqrt, IEEE remainder, C90 fmod, nextafter, nexttoward. @@ -186,10 +188,12 @@ opStatus multiply(const APFloat &, roundingMode); opStatus divide(const APFloat &, roundingMode); opStatus mod(const APFloat &, roundingMode); - void copySign(const APFloat &); opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode); - void changeSign(); // neg - void clearSign(); // abs + + /* Sign operations. */ + void changeSign(); + void clearSign(); + void copySign(const APFloat &); /* Conversions. */ opStatus convert(const fltSemantics &, roundingMode); @@ -272,8 +276,12 @@ opStatus convertFromUnsignedParts(const integerPart *, unsigned int, roundingMode); opStatus convertFromHexadecimalString(const char *, roundingMode); + opStatus convertFromDecimalString (const char *, roundingMode); char *convertNormalToHexString(char *, unsigned int, bool, roundingMode) const; + opStatus roundSignificandWithExponent(const integerPart *, unsigned int, + int, roundingMode); + APInt convertFloatAPFloatToAPInt() const; APInt convertDoubleAPFloatToAPInt() const; APInt convertF80LongDoubleAPFloatToAPInt() const; Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=42912&r1=42911&r2=42912&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Fri Oct 12 11:02:31 2007 @@ -52,6 +52,23 @@ // onto the usual format above. For now only storage of constants of // this type is supported, no arithmetic. const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022, 106 }; + + /* A tight upper bound on number of parts required to hold the value + pow(5, power) is + + power * 1024 / (441 * integerPartWidth) + 1 + + However, whilst the result may require only this many parts, + because we are multiplying two values to get it, the + multiplication may require an extra part with the excess part + being zero (consider the trivial case of 1 * 1, tcFullMultiply + requires two parts to hold the single-part result). So we add an + extra one to guarantee enough space whilst multiplying. */ + const unsigned int maxExponent = 16383; + const unsigned int maxPrecision = 113; + const unsigned int maxPowerOfFiveExponent = maxExponent + maxPrecision - 1; + const unsigned int maxPowerOfFiveParts = 2 + ((maxPowerOfFiveExponent * 1024) + / (441 * integerPartWidth)); } /* Put a bunch of private, handy routines in an anonymous namespace. */ @@ -76,7 +93,7 @@ } unsigned int - hexDigitValue (unsigned int c) + hexDigitValue(unsigned int c) { unsigned int r; @@ -239,6 +256,142 @@ return moreSignificant; } + /* The error from the true value, in half-ulps, on multiplying two + floating point numbers, which differ from the value they + approximate by at most HUE1 and HUE2 half-ulps, is strictly less + than the returned value. + + See "How to Read Floating Point Numbers Accurately" by William D + Clinger. */ + unsigned int + HUerrBound(bool inexactMultiply, unsigned int HUerr1, unsigned int HUerr2) + { + assert(HUerr1 < 2 || HUerr2 < 2 || (HUerr1 + HUerr2 < 8)); + + if (HUerr1 + HUerr2 == 0) + return inexactMultiply * 2; /* <= inexactMultiply half-ulps. */ + else + return inexactMultiply + 2 * (HUerr1 + HUerr2); + } + + /* The number of ulps from the boundary (zero, or half if ISNEAREST) + when the least significant BITS are truncated. BITS cannot be + zero. */ + integerPart + ulpsFromBoundary(const integerPart *parts, unsigned int bits, bool isNearest) + { + unsigned int count, partBits; + integerPart part, boundary; + + assert (bits != 0); + + bits--; + count = bits / integerPartWidth; + partBits = bits % integerPartWidth + 1; + + part = parts[count] & (~(integerPart) 0 >> (integerPartWidth - partBits)); + + if (isNearest) + boundary = (integerPart) 1 << (partBits - 1); + else + boundary = 0; + + if (count == 0) { + if (part - boundary <= boundary - part) + return part - boundary; + else + return boundary - part; + } + + if (part == boundary) { + while (--count) + if (parts[count]) + return ~(integerPart) 0; /* A lot. */ + + return parts[0]; + } else if (part == boundary - 1) { + while (--count) + if (~parts[count]) + return ~(integerPart) 0; /* A lot. */ + + return -parts[0]; + } + + return ~(integerPart) 0; /* A lot. */ + } + + /* Place pow(5, power) in DST, and return the number of parts used. + DST must be at least one part larger than size of the answer. */ + static unsigned int + powerOf5(integerPart *dst, unsigned int power) + { + /* A tight upper bound on number of parts required to hold the + value pow(5, power) is + + power * 65536 / (28224 * integerPartWidth) + 1 + + However, whilst the result may require only N parts, because we + are multiplying two values to get it, the multiplication may + require N + 1 parts with the excess part being zero (consider + the trivial case of 1 * 1, the multiplier requires two parts to + hold the single-part result). So we add two to guarantee + enough space whilst multiplying. */ + static integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125, + 15625, 78125 }; + static integerPart pow5s[maxPowerOfFiveParts * 2 + 5] = { 78125 * 5 }; + static unsigned int partsCount[16] = { 1 }; + + integerPart scratch[maxPowerOfFiveParts], *p1, *p2, *pow5; + unsigned int result; + + assert(power <= maxExponent); + + p1 = dst; + p2 = scratch; + + *p1 = firstEightPowers[power & 7]; + power >>= 3; + + result = 1; + pow5 = pow5s; + + for (unsigned int n = 0; power; power >>= 1, n++) { + unsigned int pc; + + pc = partsCount[n]; + + /* Calculate pow(5,pow(2,n+3)) if we haven't yet. */ + if (pc == 0) { + pc = partsCount[n - 1]; + APInt::tcFullMultiply(pow5, pow5 - pc, pow5 - pc, pc, pc); + pc *= 2; + if (pow5[pc - 1] == 0) + pc--; + partsCount[n] = pc; + } + + if (power & 1) { + integerPart *tmp; + + APInt::tcFullMultiply(p2, p1, pow5, result, pc); + result += pc; + if (p2[result - 1] == 0) + result--; + + /* Now result is in p1 with partsCount parts and p2 is scratch + space. */ + tmp = p1, p1 = p2, p2 = tmp; + } + + pow5 += pc; + } + + if (p1 != dst) + APInt::tcAssign(dst, p1, result); + + return result; + } + /* Zero at the end to avoid modular arithmetic when adding one; used when rounding up during hexadecimal output. */ static const char hexDigitsLower[] = "0123456789abcdef0"; @@ -650,6 +803,9 @@ APInt::tcShiftLeft(dividend, partsCount, bit); } + /* Ensure the dividend >= divisor initially for the loop below. + Incidentally, this means that the division loop below is + guaranteed to set the integer bit to one. */ if(APInt::tcCompare(dividend, divisor, partsCount) < 0) { exponent--; APInt::tcShiftLeft(dividend, partsCount, 1); @@ -865,7 +1021,7 @@ /* Keep OMSB up-to-date. */ if(omsb > (unsigned) exponentChange) - omsb -= (unsigned) exponentChange; + omsb -= exponentChange; else omsb = 0; } @@ -916,7 +1072,6 @@ /* We have a non-zero denormal. */ assert(omsb < semantics->precision); - assert(exponent == semantics->minExponent); /* Canonicalize zeroes. */ if(omsb == 0) @@ -1751,6 +1906,195 @@ } APFloat::opStatus +APFloat::roundSignificandWithExponent(const integerPart *decSigParts, + unsigned sigPartCount, int exp, + roundingMode rounding_mode) +{ + unsigned int parts, pow5PartCount; + fltSemantics calcSemantics = { 32767, -32767, 0 }; + integerPart pow5Parts[maxPowerOfFiveParts]; + bool isNearest; + + isNearest = (rounding_mode == rmNearestTiesToEven + || rounding_mode == rmNearestTiesToAway); + + parts = partCountForBits(semantics->precision + 11); + + /* Calculate pow(5, abs(exp)). */ + pow5PartCount = powerOf5(pow5Parts, exp >= 0 ? exp: -exp); + + for (;; parts *= 2) { + opStatus sigStatus, powStatus; + unsigned int excessPrecision, truncatedBits; + + calcSemantics.precision = parts * integerPartWidth - 1; + excessPrecision = calcSemantics.precision - semantics->precision; + truncatedBits = excessPrecision; + + APFloat decSig(calcSemantics, fcZero, sign); + APFloat pow5(calcSemantics, fcZero, false); + + sigStatus = decSig.convertFromUnsignedParts(decSigParts, sigPartCount, + rmNearestTiesToEven); + powStatus = pow5.convertFromUnsignedParts(pow5Parts, pow5PartCount, + rmNearestTiesToEven); + /* Add exp, as 10^n = 5^n * 2^n. */ + decSig.exponent += exp; + + lostFraction calcLostFraction; + integerPart HUerr, HUdistance, powHUerr; + + if (exp >= 0) { + /* multiplySignificand leaves the precision-th bit set to 1. */ + calcLostFraction = decSig.multiplySignificand(pow5, NULL); + powHUerr = powStatus != opOK; + } else { + calcLostFraction = decSig.divideSignificand(pow5); + /* Denormal numbers have less precision. */ + if (decSig.exponent < semantics->minExponent) { + excessPrecision += (semantics->minExponent - decSig.exponent); + truncatedBits = excessPrecision; + if (excessPrecision > calcSemantics.precision) + excessPrecision = calcSemantics.precision; + } + /* Extra half-ulp lost in reciprocal of exponent. */ + powHUerr = 1 + powStatus != opOK; + } + + /* Both multiplySignificand and divideSignificand return the + result with the integer bit set. */ + assert (APInt::tcExtractBit + (decSig.significandParts(), calcSemantics.precision - 1) == 1); + + HUerr = HUerrBound(calcLostFraction != lfExactlyZero, sigStatus != opOK, + powHUerr); + HUdistance = 2 * ulpsFromBoundary(decSig.significandParts(), + excessPrecision, isNearest); + + /* Are we guaranteed to round correctly if we truncate? */ + if (HUdistance >= HUerr) { + APInt::tcExtract(significandParts(), partCount(), decSig.significandParts(), + calcSemantics.precision - excessPrecision, + excessPrecision); + /* Take the exponent of decSig. If we tcExtract-ed less bits + above we must adjust our exponent to compensate for the + implicit right shift. */ + exponent = (decSig.exponent + semantics->precision + - (calcSemantics.precision - excessPrecision)); + calcLostFraction = lostFractionThroughTruncation(decSig.significandParts(), + decSig.partCount(), + truncatedBits); + return normalize(rounding_mode, calcLostFraction); + } + } +} + +APFloat::opStatus +APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode) +{ + const char *dot, *firstSignificantDigit; + integerPart val, maxVal, decValue; + opStatus fs; + + /* Skip leading zeroes and any decimal point. */ + p = skipLeadingZeroesAndAnyDot(p, &dot); + firstSignificantDigit = p; + + /* The maximum number that can be multiplied by ten with any digit + added without overflowing an integerPart. */ + maxVal = (~ (integerPart) 0 - 9) / 10; + + val = 0; + while (val <= maxVal) { + if (*p == '.') { + assert(dot == 0); + dot = p++; + } + + decValue = digitValue(*p); + if (decValue == -1U) + break; + p++; + val = val * 10 + decValue; + } + + integerPart *decSignificand; + unsigned int partCount, maxPartCount; + + partCount = 0; + maxPartCount = 4; + decSignificand = new integerPart[maxPartCount]; + decSignificand[partCount++] = val; + + /* Now continue to do single-part arithmetic for as long as we can. + Then do a part multiplication, and repeat. */ + while (decValue != -1U) { + integerPart multiplier; + + val = 0; + multiplier = 1; + + while (multiplier <= maxVal) { + if (*p == '.') { + assert(dot == 0); + dot = p++; + } + + decValue = digitValue(*p); + if (decValue == -1U) + break; + p++; + multiplier *= 10; + val = val * 10 + decValue; + } + + if (partCount == maxPartCount) { + integerPart *newDecSignificand; + newDecSignificand = new integerPart[maxPartCount = partCount * 2]; + APInt::tcAssign(newDecSignificand, decSignificand, partCount); + delete [] decSignificand; + decSignificand = newDecSignificand; + } + + APInt::tcMultiplyPart(decSignificand, decSignificand, multiplier, val, + partCount, partCount + 1, false); + + /* If we used another part (likely), increase the count. */ + if (decSignificand[partCount] != 0) + partCount++; + } + + /* Now decSignificand contains the supplied significand ignoring the + decimal point. Figure out our effective exponent, which is the + specified exponent adjusted for any decimal point. */ + + if (p == firstSignificantDigit) { + /* Ignore the exponent if we are zero - we cannot overflow. */ + category = fcZero; + fs = opOK; + } else { + int decimalExponent; + + if (dot) + decimalExponent = dot + 1 - p; + else + decimalExponent = 0; + + /* Add the given exponent. */ + if (*p == 'e' || *p == 'E') + decimalExponent = totalExponent(p, decimalExponent); + + category = fcNormal; + fs = roundSignificandWithExponent(decSignificand, partCount, + decimalExponent, rounding_mode); + } + + delete [] decSignificand; + + return fs; +} + +APFloat::opStatus APFloat::convertFromString(const char *p, roundingMode rounding_mode) { assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && @@ -1763,9 +2107,8 @@ if(p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) return convertFromHexadecimalString(p + 2, rounding_mode); - - assert(0 && "Decimal to binary conversions not yet implemented"); - abort(); + else + return convertFromDecimalString(p, rounding_mode); } /* Write out a hexadecimal representation of the floating point value From neil at daikokuya.co.uk Fri Oct 12 11:05:57 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Fri, 12 Oct 2007 16:05:57 -0000 Subject: [llvm-commits] [llvm] r42913 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200710121605.l9CG5ve0019156@zion.cs.uiuc.edu> Author: neil Date: Fri Oct 12 11:05:57 2007 New Revision: 42913 URL: http://llvm.org/viewvc/llvm-project?rev=42913&view=rev Log: Remove duplicate comment. Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=42913&r1=42912&r2=42913&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Fri Oct 12 11:05:57 2007 @@ -325,17 +325,6 @@ static unsigned int powerOf5(integerPart *dst, unsigned int power) { - /* A tight upper bound on number of parts required to hold the - value pow(5, power) is - - power * 65536 / (28224 * integerPartWidth) + 1 - - However, whilst the result may require only N parts, because we - are multiplying two values to get it, the multiplication may - require N + 1 parts with the excess part being zero (consider - the trivial case of 1 * 1, the multiplier requires two parts to - hold the single-part result). So we add two to guarantee - enough space whilst multiplying. */ static integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125, 15625, 78125 }; static integerPart pow5s[maxPowerOfFiveParts * 2 + 5] = { 78125 * 5 }; From evan.cheng at apple.com Fri Oct 12 12:16:51 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 Oct 2007 17:16:51 -0000 Subject: [llvm-commits] [llvm] r42916 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200710121716.l9CHGpjT023251@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 12:16:50 2007 New Revision: 42916 URL: http://llvm.org/viewvc/llvm-project?rev=42916&view=rev Log: Did mean to leave this in. INSERT_SUBREG isn't being coalesced yet. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=42916&r1=42915&r2=42916&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Fri Oct 12 12:16:50 2007 @@ -448,8 +448,7 @@ unsigned SrcReg, DstReg; if (tii_->isMoveInstr(*mi, SrcReg, DstReg)) ValNo = interval.getNextValue(defIndex, SrcReg, VNInfoAllocator); - else if (mi->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG || - mi->getOpcode() == TargetInstrInfo::INSERT_SUBREG) + else if (mi->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) ValNo = interval.getNextValue(defIndex, mi->getOperand(1).getReg(), VNInfoAllocator); else From clattner at apple.com Fri Oct 12 12:24:00 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 12 Oct 2007 10:24:00 -0700 Subject: [llvm-commits] [llvm] r42864 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll In-Reply-To: References: <200710111722.l9BHM0Ll024990@zion.cs.uiuc.edu> Message-ID: On Oct 11, 2007, at 10:46 AM, Dale Johannesen wrote: > You aren't checking alignment when choosing the new pointer type. > Are you sure this works on machines that don't have misaligned load/ > store? The codegen should handle unaligned loads. Devang is setting the alignment of the load correctly it appears. If the codegen doesn't respect this, then it is a legalize bug :) > In general memcpy handling is highly target specific. I'd be wary of > doing too > much in target-independent code, although I think the general idea > here is OK. Some motivation: There are two related issues in the mid-level optimizer. First, memset/memcpy are not well understood by the aliasing machinery, so they can cause some pessimizations. There is a bugzilla enhancement request about this. Second, doing the lowering in the code generator misses some optimizations. For example "strcpy(p, "x")" should turn into a single 16-bit store. This does happen in the code generator currently, but then it leaves the dead "x" string in the output. Doing this in the optimizer allows the string to be deleted. Still missing is the ability to tell that the load is coming from a constant string and using a an integer constant instead of the load. For example: void foo(char *P) { strcpy(P, "abc"); } produces: @.str = internal constant [4 x i8] c"abc\00" ; <[4 x i8]*> [#uses=1] define void @foo(i8* %P) { entry: %P1 = bitcast i8* %P to i32* ; [#uses=1] %tmp = load i32* bitcast ([4 x i8]* @.str to i32*), align 1 ; [#uses=1] store i32 %tmp, i32* %P1, align 1 ret void } Instcombine should now be taught that: @.str = internal constant [4 x i8] c"abc\00" ; <[4 x i8]*> [#uses=1] .. %tmp = load i32* bitcast ([4 x i8]* @.str to i32*), align 1 ; [#uses=1] can always be replaced with the corresponding integer immediate (independent of memcpy lowering). This will make the string dead. -Chris From clattner at apple.com Fri Oct 12 12:30:55 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 12 Oct 2007 10:30:55 -0700 Subject: [llvm-commits] [llvm] r42864 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll In-Reply-To: References: <200710111722.l9BHM0Ll024990@zion.cs.uiuc.edu> Message-ID: <35877336-ACB2-44E7-AB15-AA3C3A1B0BF9@apple.com> >>> In general memcpy handling is highly target specific. I'd be wary >>> of doing too >>> much in target-independent code, although I think the general idea >>> here is OK. >> >> I'm expecting target specific code generator to handle this if it >> is handling unaligned memcpy. >> No ? > > Might well work, I'm not sure what order things are done in. Could > you try it? PPC for example. Heh, ouch. :) We are doing the safe thing, but generating horrible horrible code (below). The DAG combiner should be able to see through the masking/shifting to allow each byte of the store to directly use the corresponding load. This is probably just a matter of having DAGCombiner::visitSTORE call TLI.SimplifyDemandedBits, indicating which bits it is actually reading. Can someone looking into adding this enhancement to dag combine? -Chris void foo(char *P) { strcpy(P, "abc"); } void bar(char *P) { strcpy(P, "a"); } ARM: _foo: ldr r3, LCPI0__foo ldrb r2, [r3, #+3] ldrb r1, [r3, #+2] orr r2, r1, r2, lsl #8 ldrb r1, [r3, #+1] ldrb r3, [r3] orr r3, r3, r1, lsl #8 orr r3, r3, r2, lsl #16 strb r3, [r0] mov r2, r3, lsr #24 strb r2, [r0, #+3] mov r2, r3, lsr #16 strb r2, [r0, #+2] mov r3, r3, lsr #8 strb r3, [r0, #+1] bx lr _bar: ldr r3, LCPI0__bar ldrb r2, [r3, #+1] ldrb r3, [r3] orr r3, r3, r2, lsl #8 strb r3, [r0] mov r3, r3, lsr #8 strb r3, [r0, #+1] bx lr PPC: _foo: lis r2, ha16(_.str) lbz r4, lo16(_.str)(r2) la r2, lo16(_.str)(r2) lbz r5, 2(r2) lbz r6, 1(r2) lbz r2, 3(r2) slwi r4, r4, 8 slwi r5, r5, 8 rlwimi r4, r6, 0, 24, 31 rlwimi r5, r2, 0, 24, 31 slwi r2, r4, 16 rlwimi r2, r5, 0, 16, 31 srwi r4, r2, 24 srwi r5, r2, 8 srwi r6, r2, 16 stb r4, 0(r3) stb r6, 1(r3) stb r5, 2(r3) stb r2, 3(r3) blr _bar: lis r2, ha16(_.str1) lbz r4, lo16(_.str1)(r2) la r2, lo16(_.str1)(r2) lbz r2, 1(r2) slwi r4, r4, 8 rlwimi r4, r2, 0, 24, 31 srwi r2, r4, 8 stb r2, 0(r3) stb r4, 1(r3) blr From sabre at nondot.org Fri Oct 12 12:49:52 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 12 Oct 2007 17:49:52 -0000 Subject: [llvm-commits] [llvm] r42918 - /llvm/trunk/include/llvm/ADT/StringMap.h Message-ID: <200710121749.l9CHnqUg024836@zion.cs.uiuc.edu> Author: lattner Date: Fri Oct 12 12:49:52 2007 New Revision: 42918 URL: http://llvm.org/viewvc/llvm-project?rev=42918&view=rev Log: Make this compute the correct offset, handling alignment of the element pointer correctly. Modified: llvm/trunk/include/llvm/ADT/StringMap.h Modified: llvm/trunk/include/llvm/ADT/StringMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringMap.h?rev=42918&r1=42917&r2=42918&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/StringMap.h (original) +++ llvm/trunk/include/llvm/ADT/StringMap.h Fri Oct 12 12:49:52 2007 @@ -171,8 +171,9 @@ /// GetStringMapEntryFromValue - Given a value that is known to be embedded /// into a StringMapEntry, return the StringMapEntry itself. static StringMapEntry &GetStringMapEntryFromValue(ValueTy &V) { - return *reinterpret_cast(reinterpret_cast(&V) - - sizeof(StringMapEntryBase)); + StringMapEntry *EPtr = 0; + char *Ptr = reinterpret_cast(&V) - (intptr_t)&EPtr->Val; + return *reinterpret_cast(Ptr); } static const StringMapEntry &GetStringMapEntryFromValue(const ValueTy &V) { return GetStringMapEntryFromValue(const_cast(V)); From dalej at apple.com Fri Oct 12 12:52:03 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 12 Oct 2007 17:52:03 -0000 Subject: [llvm-commits] [llvm] r42919 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200710121752.l9CHq3wO024947@zion.cs.uiuc.edu> Author: johannes Date: Fri Oct 12 12:52:03 2007 New Revision: 42919 URL: http://llvm.org/viewvc/llvm-project?rev=42919&view=rev Log: Implement i64->ppcf128 conversions. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=42919&r1=42918&r2=42919&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Oct 12 12:52:03 2007 @@ -6032,7 +6032,7 @@ case ISD::UINT_TO_FP: { bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP; MVT::ValueType SrcVT = Node->getOperand(0).getValueType(); - if (VT == MVT::ppcf128) { + if (VT == MVT::ppcf128 && SrcVT != MVT::i64) { static uint64_t zero = 0; if (isSigned) { Hi = LegalizeOp(DAG.getNode(ISD::SINT_TO_FP, MVT::f64, @@ -6044,6 +6044,7 @@ Node->getOperand(0))); Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &zero)), MVT::f64); Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi); + // X>=0 ? {(f64)x, 0} : {(f64)x, 0} + 2^32 ExpandOp(DAG.getNode(ISD::SELECT_CC, MVT::ppcf128, Node->getOperand(0), DAG.getConstant(0, MVT::i32), DAG.getNode(ISD::FADD, MVT::ppcf128, Hi, @@ -6056,6 +6057,24 @@ } break; } + if (VT == MVT::ppcf128 && SrcVT == MVT::i64 && !isSigned) { + // si64->ppcf128 done by libcall, below + static uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 }; + ExpandOp(DAG.getNode(ISD::SINT_TO_FP, MVT::ppcf128, Node->getOperand(0)), + Lo, Hi); + Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi); + // x>=0 ? (ppcf128)(i64)x : (ppcf128)(i64)x + 2^64 + ExpandOp(DAG.getNode(ISD::SELECT_CC, MVT::ppcf128, Node->getOperand(0), + DAG.getConstant(0, MVT::i64), + DAG.getNode(ISD::FADD, MVT::ppcf128, Hi, + DAG.getConstantFP( + APFloat(APInt(128, 2, TwoE64)), + MVT::ppcf128)), + Hi, + DAG.getCondCode(ISD::SETLT)), + Lo, Hi); + break; + } RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; if (Node->getOperand(0).getValueType() == MVT::i64) { if (VT == MVT::f32) From sabre at nondot.org Fri Oct 12 13:05:47 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 12 Oct 2007 18:05:47 -0000 Subject: [llvm-commits] [llvm] r42920 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2007-10-12-Crash.ll Message-ID: <200710121805.l9CI5lcv025632@zion.cs.uiuc.edu> Author: lattner Date: Fri Oct 12 13:05:47 2007 New Revision: 42920 URL: http://llvm.org/viewvc/llvm-project?rev=42920&view=rev Log: Fix a bug in my patch last night that broke InstCombine/2007-10-12-Crash.ll Added: llvm/trunk/test/Transforms/InstCombine/2007-10-12-Crash.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=42920&r1=42919&r2=42920&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Fri Oct 12 13:05:47 2007 @@ -8643,8 +8643,14 @@ // converted to match the type of the cast, don't touch this. if (isa(BCI->getOperand(0))) { // See if the bitcast simplifies, if so, don't nuke this GEP yet. - if (visitBitCast(*BCI)) + if (Instruction *I = visitBitCast(*BCI)) { + if (I != BCI) { + I->takeName(BCI); + BCI->getParent()->getInstList().insert(BCI, I); + ReplaceInstUsesWith(*BCI, I); + } return &GEP; + } } return new BitCastInst(BCI->getOperand(0), GEP.getType()); } Added: llvm/trunk/test/Transforms/InstCombine/2007-10-12-Crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2007-10-12-Crash.ll?rev=42920&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2007-10-12-Crash.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/2007-10-12-Crash.ll Fri Oct 12 13:05:47 2007 @@ -0,0 +1,38 @@ +; RUN: llvm-as < %s | opt -instcombine -disable-output + + %struct.Ray = type { %struct.Vec, %struct.Vec } + %struct.Scene = type { i32 (...)** } + %struct.Vec = type { double, double, double } + +declare double @_Z9ray_traceRK3VecRK3RayRK5Scene(%struct.Vec*, %struct.Ray*, %struct.Scene*) + +define i32 @main(i32 %argc, i8** %argv) { +entry: + %tmp3 = alloca %struct.Ray, align 4 ; <%struct.Ray*> [#uses=2] + %tmp97 = icmp slt i32 0, 512 ; [#uses=1] + br i1 %tmp97, label %bb71, label %bb108 + +bb29: ; preds = %bb62 + %tmp322 = bitcast %struct.Ray* %tmp3 to %struct.Vec* ; <%struct.Vec*> [#uses=1] + %tmp322.0 = getelementptr %struct.Vec* %tmp322, i32 0, i32 0 ; [#uses=1] + store double 0.000000e+00, double* %tmp322.0 + %tmp57 = call double @_Z9ray_traceRK3VecRK3RayRK5Scene( %struct.Vec* null, %struct.Ray* %tmp3, %struct.Scene* null ) ; [#uses=0] + br label %bb62 + +bb62: ; preds = %bb71, %bb29 + %tmp65 = icmp slt i32 0, 4 ; [#uses=1] + br i1 %tmp65, label %bb29, label %bb68 + +bb68: ; preds = %bb62 + ret i32 0 + +bb71: ; preds = %entry + %tmp74 = icmp slt i32 0, 4 ; [#uses=1] + br i1 %tmp74, label %bb62, label %bb77 + +bb77: ; preds = %bb71 + ret i32 0 + +bb108: ; preds = %entry + ret i32 0 +} From sabre at nondot.org Fri Oct 12 13:16:23 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 12 Oct 2007 18:16:23 -0000 Subject: [llvm-commits] [llvm] r42921 - /llvm/trunk/include/llvm/ADT/StringMap.h Message-ID: <200710121816.l9CIGNBM026301@zion.cs.uiuc.edu> Author: lattner Date: Fri Oct 12 13:16:23 2007 New Revision: 42921 URL: http://llvm.org/viewvc/llvm-project?rev=42921&view=rev Log: don't use intptr_t without including it. Modified: llvm/trunk/include/llvm/ADT/StringMap.h Modified: llvm/trunk/include/llvm/ADT/StringMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringMap.h?rev=42921&r1=42920&r2=42921&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/StringMap.h (original) +++ llvm/trunk/include/llvm/ADT/StringMap.h Fri Oct 12 13:16:23 2007 @@ -172,7 +172,9 @@ /// into a StringMapEntry, return the StringMapEntry itself. static StringMapEntry &GetStringMapEntryFromValue(ValueTy &V) { StringMapEntry *EPtr = 0; - char *Ptr = reinterpret_cast(&V) - (intptr_t)&EPtr->Val; + char *Ptr = reinterpret_cast(&V) - + (reinterpret_cast(&EPtr->Val) - + reinterpret_cast(EPtr)); return *reinterpret_cast(Ptr); } static const StringMapEntry &GetStringMapEntryFromValue(const ValueTy &V) { From evan.cheng at apple.com Fri Oct 12 13:22:55 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 Oct 2007 18:22:55 -0000 Subject: [llvm-commits] [llvm] r42922 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200710121822.l9CIMt14026923@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 13:22:55 2007 New Revision: 42922 URL: http://llvm.org/viewvc/llvm-project?rev=42922&view=rev Log: Update. Modified: llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=42922&r1=42921&r2=42922&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Fri Oct 12 13:22:55 2007 @@ -89,6 +89,8 @@ Leave any_extend as pseudo instruction and hint to register allocator. Delay codegen until post register allocation. +Note. any_extend is now turned into an INSERT_SUBREG. We still need to teach +the coalescer how to deal with it though. //===---------------------------------------------------------------------===// @@ -991,24 +993,6 @@ //===---------------------------------------------------------------------===// -This: -#include -unsigned test(float f) { - return _mm_cvtsi128_si32( (__m128i) _mm_set_ss( f )); -} - -Compiles to: -_test: - movss 4(%esp), %xmm0 - movd %xmm0, %eax - ret - -it should compile to a move from the stack slot directly into eax. DAGCombine -has this xform, but it is currently disabled until the alignment fields of -the load/store nodes are trustworthy. - -//===---------------------------------------------------------------------===// - Sometimes it is better to codegen subtractions from a constant (e.g. 7-x) with a neg instead of a sub instruction. Consider: From dalej at apple.com Fri Oct 12 14:02:18 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 12 Oct 2007 19:02:18 -0000 Subject: [llvm-commits] [llvm] r42924 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200710121902.l9CJ2Isu029913@zion.cs.uiuc.edu> Author: johannes Date: Fri Oct 12 14:02:17 2007 New Revision: 42924 URL: http://llvm.org/viewvc/llvm-project?rev=42924&view=rev Log: ppc long double. Implement fabs and fneg. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=42924&r1=42923&r2=42924&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Oct 12 14:02:17 2007 @@ -6001,6 +6001,16 @@ break; } case ISD::FABS: { + if (VT == MVT::ppcf128) { + SDOperand Tmp; + ExpandOp(Node->getOperand(0), Lo, Tmp); + Hi = DAG.getNode(ISD::FABS, NVT, Tmp); + // lo = hi==fabs(hi) ? lo : -lo; + Lo = DAG.getNode(ISD::SELECT_CC, NVT, Hi, Tmp, + Lo, DAG.getNode(ISD::FNEG, NVT, Lo), + DAG.getCondCode(ISD::SETEQ)); + break; + } SDOperand Mask = (VT == MVT::f64) ? DAG.getConstantFP(BitsToDouble(~(1ULL << 63)), VT) : DAG.getConstantFP(BitsToFloat(~(1U << 31)), VT); @@ -6012,6 +6022,12 @@ break; } case ISD::FNEG: { + if (VT == MVT::ppcf128) { + ExpandOp(Node->getOperand(0), Lo, Hi); + Lo = DAG.getNode(ISD::FNEG, MVT::f64, Lo); + Hi = DAG.getNode(ISD::FNEG, MVT::f64, Hi); + break; + } SDOperand Mask = (VT == MVT::f64) ? DAG.getConstantFP(BitsToDouble(1ULL << 63), VT) : DAG.getConstantFP(BitsToFloat(1U << 31), VT); From lattner at apple.com Fri Oct 12 14:20:58 2007 From: lattner at apple.com (Tanya Lattner) Date: Fri, 12 Oct 2007 12:20:58 -0700 Subject: [llvm-commits] darwin x86 make check failures Message-ID: <469C38F9-E8FE-4ABF-A64B-C5C4F61AEB35@apple.com> I'm seeing this with tot (SVN version 42924): FAIL: /Users/lattner/work/llvm/test/CodeGen/X86/2006-10-19- SwitchUnnecessaryBranching.ll Failed with exit(1) at line 1 while running: llvm-upgrade < /Users/lattner/work/llvm/test/CodeGen/ X86/2006-10-19-SwitchUnnecessaryBranching.ll | llvm-as | llc - march=x86 | /usr/bin/tclsh8.4 /Users/lattner/work/llvm/test/Scripts/ prcontext.tcl je 1 | grep BB1_main: child process exited abnormally FAIL: /Users/lattner/work/llvm/test/CodeGen/X86/fp_constant_op.llx Failed with exit(1) at line 1 while running: llvm-upgrade < /Users/lattner/work/llvm/test/CodeGen/ X86/fp_constant_op.llx | llvm-as | llc -march=x86 -x86-asm- syntax=intel -mcpu=i486 | grep -i ST | not grep {fadd\|fsub\|fdiv\| fmul} child process exited abnormally Anyone want to claim them? ;) -Tanya From baldrick at free.fr Fri Oct 12 14:37:31 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 12 Oct 2007 19:37:31 -0000 Subject: [llvm-commits] [llvm] r42925 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200710121937.l9CJbV5s031330@zion.cs.uiuc.edu> Author: baldrick Date: Fri Oct 12 14:37:31 2007 New Revision: 42925 URL: http://llvm.org/viewvc/llvm-project?rev=42925&view=rev Log: Due to the new tail call optimization, trampolines can no longer be created for fastcc functions. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=42925&r1=42924&r2=42925&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Oct 12 14:37:31 2007 @@ -4878,7 +4878,6 @@ default: assert(0 && "Unsupported calling convention"); case CallingConv::C: - case CallingConv::Fast: case CallingConv::X86_StdCall: { // Pass 'nest' parameter in ECX. // Must be kept in sync with X86CallingConv.td From gordonhenriksen at mac.com Fri Oct 12 14:48:14 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Fri, 12 Oct 2007 19:48:14 -0000 Subject: [llvm-commits] [llvm] r42927 - /llvm/trunk/bindings/ocaml/Makefile.ocaml Message-ID: <200710121948.l9CJmEav031722@zion.cs.uiuc.edu> Author: gordon Date: Fri Oct 12 14:48:13 2007 New Revision: 42927 URL: http://llvm.org/viewvc/llvm-project?rev=42927&view=rev Log: Fix ocaml bindings for picky linkers. :) Thanks to T?r?k Edvin for helping to track this down. Modified: llvm/trunk/bindings/ocaml/Makefile.ocaml Modified: llvm/trunk/bindings/ocaml/Makefile.ocaml URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/Makefile.ocaml?rev=42927&r1=42926&r2=42927&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/Makefile.ocaml (original) +++ llvm/trunk/bindings/ocaml/Makefile.ocaml Fri Oct 12 14:48:13 2007 @@ -38,8 +38,9 @@ # Tools OCAMLCFLAGS += -I $(OcamlDir) -I $(ObjDir) OCAMLAFLAGS += $(patsubst %,-cclib %, \ - $(filter-out -L$(LibDir),$(shell $(LLVM_CONFIG) --ldflags)) \ - $(UsedLibs) -l$(LIBRARYNAME)) + $(filter-out -L$(LibDir),-l$(LIBRARYNAME) \ + $(shell $(LLVM_CONFIG) --ldflags)) \ + $(UsedLibs)) Compile.CMI := $(strip $(OCAMLC) -c $(OCAMLCFLAGS) -o) Compile.CMO := $(strip $(OCAMLC) -c $(OCAMLCFLAGS) -o) From dpatel at apple.com Fri Oct 12 15:04:24 2007 From: dpatel at apple.com (Devang Patel) Date: Fri, 12 Oct 2007 20:04:24 -0000 Subject: [llvm-commits] [llvm] r42929 - /llvm/trunk/test/Transforms/LoopIndexSplit/Output/ Message-ID: <200710122004.l9CK4OqS032355@zion.cs.uiuc.edu> Author: dpatel Date: Fri Oct 12 15:04:24 2007 New Revision: 42929 URL: http://llvm.org/viewvc/llvm-project?rev=42929&view=rev Log: t Removed: llvm/trunk/test/Transforms/LoopIndexSplit/Output/ From dpatel at apple.com Fri Oct 12 15:10:21 2007 From: dpatel at apple.com (Devang Patel) Date: Fri, 12 Oct 2007 20:10:21 -0000 Subject: [llvm-commits] [llvm] r42930 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200710122010.l9CKALGj032645@zion.cs.uiuc.edu> Author: dpatel Date: Fri Oct 12 15:10:21 2007 New Revision: 42930 URL: http://llvm.org/viewvc/llvm-project?rev=42930&view=rev Log: Dest type is always i8 *. This allows some simplification. Do not filter memmove. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=42930&r1=42929&r2=42930&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Fri Oct 12 15:10:21 2007 @@ -7669,43 +7669,22 @@ // If MemCpyInst length is 1/2/4/8 bytes then replace memcpy with // load/store. ConstantInt *MemOpLength = dyn_cast(CI.getOperand(3)); - if (isa(MI)) - if (MemOpLength) { + if (MemOpLength) { unsigned Size = MemOpLength->getZExtValue(); unsigned Align = cast(CI.getOperand(4))->getZExtValue(); - const PointerType *PTy = cast(CI.getOperand(1)->getType()); - const Type *MTy = PTy->getElementType(); PointerType *NewPtrTy = NULL; - if (MTy == Type::Int8Ty) { - if (Size == 8) - NewPtrTy = PointerType::get(Type::Int64Ty); - else if (Size == 4) - NewPtrTy = PointerType::get(Type::Int32Ty); - else if (Size == 2) - NewPtrTy = PointerType::get(Type::Int16Ty); - else if (Size == 1) - NewPtrTy = PointerType::get(Type::Int8Ty); - } else if (MTy == Type::Int16Ty) { - if (Size == 4) - NewPtrTy = PointerType::get(Type::Int64Ty); - else if (Size == 2) - NewPtrTy = PointerType::get(Type::Int32Ty); - else if (Size == 1) - NewPtrTy = PointerType::get(Type::Int16Ty); - } else if (MTy == Type::Int32Ty) { - if (Size == 2) - NewPtrTy = PointerType::get(Type::Int64Ty); - else if (Size == 1) - NewPtrTy = PointerType::get(Type::Int32Ty); - } else if (MTy == Type::Int64Ty) { - if (Size == 1) - NewPtrTy = PointerType::get(Type::Int64Ty); - } + // Destination pointer type is always i8 * + if (Size == 8) + NewPtrTy = PointerType::get(Type::Int64Ty); + else if (Size == 4) + NewPtrTy = PointerType::get(Type::Int32Ty); + else if (Size == 2) + NewPtrTy = PointerType::get(Type::Int16Ty); + else if (Size == 1) + NewPtrTy = PointerType::get(Type::Int8Ty); if (NewPtrTy) { - Value *Src = - InsertCastBefore(Instruction::BitCast,CI.getOperand(2),NewPtrTy,CI); - Value *Dest = - InsertCastBefore(Instruction::BitCast,CI.getOperand(1),NewPtrTy,CI); + Value *Src = InsertCastBefore(Instruction::BitCast, CI.getOperand(2), NewPtrTy, CI); + Value *Dest = InsertCastBefore(Instruction::BitCast, CI.getOperand(1), NewPtrTy, CI); Value *L = new LoadInst(Src, "tmp", false, Align, &CI); Value *NS = new StoreInst(L, Dest, false, Align, &CI); CI.replaceAllUsesWith(NS); From dalej at apple.com Fri Oct 12 15:40:40 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 12 Oct 2007 13:40:40 -0700 Subject: [llvm-commits] darwin x86 make check failures In-Reply-To: <469C38F9-E8FE-4ABF-A64B-C5C4F61AEB35@apple.com> References: <469C38F9-E8FE-4ABF-A64B-C5C4F61AEB35@apple.com> Message-ID: <82167765-5A14-490C-AF9E-A75B30A6935E@apple.com> On Oct 12, 2007, at 12:20 PM, Tanya Lattner wrote: > Anyone want to claim them? ;) I confirm this is happening, but it was not happening until I did a checkout. 2006-10-19-SwitchUnnecessaryBranching.ll was introduced by the change in label names. It looks like there was an attempt to fix it once, so it's probably OS dependent. On darwin it's trying to match LBB1__main (2 underscores) with BB1_main (1 underscore). The other one is failing doing grep -i ST | not grep {fadd\\|fsub\\|fdiv\\|fmul} There are no lines that match ST (correctly IMO). I would expect "not grep" to succeed on null input, but apparently it doesn't. It's not obvious what the grep for ST is trying to do, but I doubt this is still testing what it was supposed to test. From djg at cray.com Fri Oct 12 15:42:14 2007 From: djg at cray.com (Dan Gohman) Date: Fri, 12 Oct 2007 20:42:14 -0000 Subject: [llvm-commits] [llvm] r42932 - /llvm/trunk/test/CodeGen/X86/fp_constant_op.llx Message-ID: <200710122042.l9CKgE7P002337@zion.cs.uiuc.edu> Author: djg Date: Fri Oct 12 15:42:14 2007 New Revision: 42932 URL: http://llvm.org/viewvc/llvm-project?rev=42932&view=rev Log: Fix this test to not depend on the assembly output containing something that includes the string "st". This probably fixes the regression on Darwin. Modified: llvm/trunk/test/CodeGen/X86/fp_constant_op.llx Modified: llvm/trunk/test/CodeGen/X86/fp_constant_op.llx URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fp_constant_op.llx?rev=42932&r1=42931&r2=42932&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/fp_constant_op.llx (original) +++ llvm/trunk/test/CodeGen/X86/fp_constant_op.llx Fri Oct 12 15:42:14 2007 @@ -1,5 +1,5 @@ ; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86 -x86-asm-syntax=intel -mcpu=i486 | \ -; RUN: grep -i ST | not grep {fadd\\|fsub\\|fdiv\\|fmul} +; RUN: grep {fadd\\|fsub\\|fdiv\\|fmul} | not grep -i ST ; Test that the load of the constant is folded into the operation. From djg at cray.com Fri Oct 12 15:48:29 2007 From: djg at cray.com (Dan Gohman) Date: Fri, 12 Oct 2007 15:48:29 -0500 Subject: [llvm-commits] darwin x86 make check failures Message-ID: <20071012204829.GD21991@village.us.cray.com> >> Anyone want to claim them? ;) > > I confirm this is happening, but it was not happening until I did a > checkout. They're both due to 42908. > 2006-10-19-SwitchUnnecessaryBranching.ll was introduced by the change > in label names. > It looks like there was an attempt to fix it once, so it's probably > OS dependent. On darwin > it's trying to match LBB1__main (2 underscores) with BB1_main (1 > underscore). I'll add a target triple to make this one behave consistently. > The other one is failing doing > grep -i ST | not grep {fadd\\|fsub\\|fdiv\\|fmul} > > There are no lines that match ST (correctly IMO). I would expect > "not grep" to succeed > on null input, but apparently it doesn't. It's not obvious what the > grep for ST is trying to > do, but I doubt this is still testing what it was supposed to test. I just submitted a fix for this one. I believe it now tests what it's supposed to. Dan -- Dan Gohman, Cray Inc. From dalej at apple.com Fri Oct 12 15:51:13 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 12 Oct 2007 13:51:13 -0700 Subject: [llvm-commits] [llvm] r42932 - /llvm/trunk/test/CodeGen/X86/fp_constant_op.llx In-Reply-To: <200710122042.l9CKgE7P002337@zion.cs.uiuc.edu> References: <200710122042.l9CKgE7P002337@zion.cs.uiuc.edu> Message-ID: On Oct 12, 2007, at 1:42 PM, Dan Gohman wrote: > Author: djg > Date: Fri Oct 12 15:42:14 2007 > New Revision: 42932 > > URL: http://llvm.org/viewvc/llvm-project?rev=42932&view=rev > Log: > Fix this test to not depend on the assembly output containing > something > that includes the string "st". This probably fixes the regression on > Darwin. Yes, it does. From arnold.schwaighofer at gmail.com Fri Oct 12 16:30:58 2007 From: arnold.schwaighofer at gmail.com (Arnold Schwaighofer) Date: Fri, 12 Oct 2007 21:30:58 -0000 Subject: [llvm-commits] [llvm] r42934 - in /llvm/trunk: include/llvm/Target/TargetLowering.h include/llvm/Target/TargetOptions.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/X86/README.txt lib/Target/X86/X86.td lib/Target/X86/X86CallingConv.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrFPStack.td lib/Target/X86/X86InstrInfo.td lib/Target/X86/X86InstrSSE.td lib/Target/X86/X86InstrX86-64.td lib/Target/X86/X86RegisterInfo.td Message-ID: <200710122130.l9CLUwqF004585@zion.cs.uiuc.edu> Author: arnolds Date: Fri Oct 12 16:30:57 2007 New Revision: 42934 URL: http://llvm.org/viewvc/llvm-project?rev=42934&view=rev Log: Corrected many typing errors. And removed 'nest' parameter handling for fastcc from X86CallingConv.td. This means that nested functions are not supported for calling convention 'fastcc'. Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/include/llvm/Target/TargetOptions.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/Target/X86/README.txt llvm/trunk/lib/Target/X86/X86.td llvm/trunk/lib/Target/X86/X86CallingConv.td llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86InstrFPStack.td llvm/trunk/lib/Target/X86/X86InstrInfo.td llvm/trunk/lib/Target/X86/X86InstrSSE.td llvm/trunk/lib/Target/X86/X86InstrX86-64.td llvm/trunk/lib/Target/X86/X86RegisterInfo.td Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=42934&r1=42933&r2=42934&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Fri Oct 12 16:30:57 2007 @@ -861,8 +861,8 @@ virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); /// IsEligibleForTailCallOptimization - Check whether the call is eligible for - /// tail call optimization. Target which want to do tail call optimization - /// should implement this function. + /// tail call optimization. Targets which want to do tail call optimization + /// should override this function. virtual bool IsEligibleForTailCallOptimization(SDOperand Call, SDOperand Ret, SelectionDAG &DAG) const { Modified: llvm/trunk/include/llvm/Target/TargetOptions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetOptions.h?rev=42934&r1=42933&r2=42934&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetOptions.h (original) +++ llvm/trunk/include/llvm/Target/TargetOptions.h Fri Oct 12 16:30:57 2007 @@ -74,9 +74,9 @@ /// be emitted. extern bool ExceptionHandling; - /// PerformTailCallOpt - This flag is enabled when the -tailcallopt is - /// specified on the commandline. When the flag is on, the target will perform - /// tail call optimization (pop the caller's stack) providing it supports it. + /// PerformTailCallOpt - This flag is enabled when -tailcallopt is specified + /// on the commandline. When the flag is on, the target will perform tail call + /// optimization (pop the caller's stack) providing it supports it. extern bool PerformTailCallOpt; } // End llvm namespace Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=42934&r1=42933&r2=42934&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Oct 12 16:30:57 2007 @@ -4476,7 +4476,7 @@ } /// CheckDAGForTailCallsAndFixThem - This Function looks for CALL nodes in the -/// DAG and fixes their tailcall attribute operand +/// DAG and fixes their tailcall attribute operand. static void CheckDAGForTailCallsAndFixThem(SelectionDAG &DAG, TargetLowering& TLI) { SDNode * Ret = NULL; @@ -4497,7 +4497,7 @@ cast(OpCall.getOperand(3))->getValue() != 0; // If CALL node has tail call attribute set to true and the call is not // eligible (no RET or the target rejects) the attribute is fixed to - // false. The TargetLowering::IsEligibleForTailCallOptimization function + // false. The TargetLowering::IsEligibleForTailCallOptimization function // must correctly identify tail call optimizable calls. if (isMarkedTailCall && (Ret==NULL || Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=42934&r1=42933&r2=42934&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Fri Oct 12 16:30:57 2007 @@ -1352,14 +1352,15 @@ L5: //===---------------------------------------------------------------------===// + Tail call optimization improvements: Tail call optimization currently -pushes all arguments on the top of the stack (their normal place if -that was a not tail call optimized functiong call ) before moving them -to actual stack slot. this is done to prevent overwriting of paramters -(see example below) that might be used, since the arguments of the -callee overwrites callers arguments. +pushes all arguments on the top of the stack (their normal place for +non-tail call optimized calls) before moving them to actual stack +slot. This is done to prevent overwriting of parameters (see example +below) that might be used, since the arguments of the callee +overwrites caller's arguments. - example: +example: int callee(int32, int64); int caller(int32 arg1, int32 arg2) { @@ -1371,39 +1372,41 @@ [arg2] -> [(int64) [RETADDR] local ] -moving arg1 onto the stack slot of callee function would overwrite +Moving arg1 onto the stack slot of callee function would overwrite arg2 of the caller. Possible optimizations: - - only push those arguments to the top of the stack that are actual + - Only push those arguments to the top of the stack that are actual parameters of the caller function and have no local value in the - caller - - in above example local does not need to be pushed onto the top of - the stack as it is definitetly not a caller's function parameter + caller. - - analyse the actual parameters of the callee to see which would - overwrite a caller paramter which is used by the callee and only - push them onto the top of the stack + In the above example local does not need to be pushed onto the top + of the stack as it is definitely not a caller's function + parameter. + + - Analyse the actual parameters of the callee to see which would + overwrite a caller parameter which is used by the callee and only + push them onto the top of the stack. int callee (int32 arg1, int32 arg2); int caller (int32 arg1, int32 arg2) { return callee(arg1,arg2); } - here we don't need to write any variables to the top of the stack - since they don't overwrite each other + Here we don't need to write any variables to the top of the stack + since they don't overwrite each other. int callee (int32 arg1, int32 arg2); int caller (int32 arg1, int32 arg2) { return callee(arg2,arg1); } - here we need to push the arguments because they overwrite each other + Here we need to push the arguments because they overwrite each + other. - code for lowering directly onto callers arguments: + Code for lowering directly onto callers arguments: + SmallVector, 8> RegsToPass; + SmallVector MemOpChains; + Modified: llvm/trunk/lib/Target/X86/X86.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.td?rev=42934&r1=42933&r2=42934&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86.td (original) +++ llvm/trunk/lib/Target/X86/X86.td Fri Oct 12 16:30:57 2007 @@ -1,4 +1,4 @@ -//===- X86.td - Target definition file for the Intel X86 arch ---*- C++ -*-===// +//===- X86.td - Target definition file for the Intel X86 ---*- tablegen -*-===// // // The LLVM Compiler Infrastructure // Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallingConv.td?rev=42934&r1=42933&r2=42934&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CallingConv.td (original) +++ llvm/trunk/lib/Target/X86/X86CallingConv.td Fri Oct 12 16:30:57 2007 @@ -1,4 +1,4 @@ -//===- X86CallingConv.td - Calling Conventions for X86 32/64 ----*- C++ -*-===// +//===- X86CallingConv.td - Calling Conventions X86 32/64 ---*- tablegen -*-===// // // The LLVM Compiler Infrastructure // @@ -127,7 +127,7 @@ CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToStack<8, 8>> ]>; -// tail call convetion (fast) one register is reserved for target address +// Tail call convention (fast): One register is reserved for target address, // namely R9 def CC_X86_64_TailCall : CallingConv<[ // Promote i8/i16 arguments to i32. @@ -207,15 +207,14 @@ CCDelegateTo ]>; -/// Same as C calling convention up to nonfree ECX which is used for storing -/// potential pointer to tail called function +/// Same as C calling convention except for non-free ECX which is used for storing +/// a potential pointer to the tail called function. def CC_X86_32_TailCall : CallingConv<[ // Promote i8/i16 arguments to i32. CCIfType<[i8, i16], CCPromoteToType>, - // The 'nest' parameter, if any, is passed in ECX. - CCIfNest>, - + // Nested functions are currently not supported by fastcc. + // The first 3 integer arguments, if marked 'inreg' and if the call is not // a vararg call, are passed in integer registers. CCIfNotVarArg>>>, Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=42934&r1=42933&r2=42934&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Oct 12 16:30:57 2007 @@ -1,4 +1,4 @@ -//===-- X86ISelLowering.cpp - X86 DAG Lowering Implementation -------------===// +//===-- X86isellowering.cpp - X86 DAG Lowering Implementation -------------===// // // The LLVM Compiler Infrastructure // @@ -1402,13 +1402,12 @@ // * elf/pic is disabled OR // * elf/pic enabled + callee is in module + callee has // visibility protected or hidden -// To ensure the stack is aligned according to platform abi pass -// tail-call-align-stack. This makes sure that argument delta is always -// multiples of stack alignment. (Dynamic linkers need this - darwin's dyld for -// example) +// To keep the stack aligned according to platform abi the function +// GetAlignedArgumentStackSize ensures that argument delta is always multiples +// of stack alignment. (Dynamic linkers need this - darwin's dyld for example) // If a tail called function callee has more arguments than the caller the // caller needs to make sure that there is room to move the RETADDR to. This is -// achived by reserving an area the size of the argument delta right after the +// achieved by reserving an area the size of the argument delta right after the // original REtADDR, but before the saved framepointer or the spilled registers // e.g. caller(arg1, arg2) calls callee(arg1, arg2,arg3,arg4) // stack layout: Modified: llvm/trunk/lib/Target/X86/X86InstrFPStack.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFPStack.td?rev=42934&r1=42933&r2=42934&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrFPStack.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrFPStack.td Fri Oct 12 16:30:57 2007 @@ -1,4 +1,4 @@ -//==- X86InstrFPStack.td - Describe the X86 Instruction Set -------*- C++ -*-=// +//==- X86InstrFPStack.td - Describe the X86 Instruction Set --*- tablegen -*-=// // // The LLVM Compiler Infrastructure // Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=42934&r1=42933&r2=42934&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Fri Oct 12 16:30:57 2007 @@ -1,4 +1,4 @@ -//===- X86InstrInfo.td - Describe the X86 Instruction Set -------*- C++ -*-===// +//===- X86InstrInfo.td - Describe the X86 Instruction Set --*- tablegen -*-===// // // The LLVM Compiler Infrastructure // Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=42934&r1=42933&r2=42934&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Fri Oct 12 16:30:57 2007 @@ -1,4 +1,4 @@ -//====- X86InstrSSE.td - Describe the X86 Instruction Set -------*- C++ -*-===// +//====- X86InstrSSE.td - Describe the X86 Instruction Set --*- tablegen -*-===// // // The LLVM Compiler Infrastructure // Modified: llvm/trunk/lib/Target/X86/X86InstrX86-64.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrX86-64.td?rev=42934&r1=42933&r2=42934&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrX86-64.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrX86-64.td Fri Oct 12 16:30:57 2007 @@ -1,4 +1,4 @@ -//====- X86InstrX86-64.td - Describe the X86 Instruction Set ----*- C++ -*-===// +//====- X86InstrX86-64.td - Describe the X86 Instr. Set ----*- tablegen -*-===// // // The LLVM Compiler Infrastructure // Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.td?rev=42934&r1=42933&r2=42934&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Fri Oct 12 16:30:57 2007 @@ -1,4 +1,4 @@ -//===- X86RegisterInfo.td - Describe the X86 Register File ------*- C++ -*-===// +//===- X86RegisterInfo.td - Describe the X86 Register File --*- tablegen -*-==// // // The LLVM Compiler Infrastructure // From isanbard at gmail.com Fri Oct 12 16:52:31 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 12 Oct 2007 14:52:31 -0700 Subject: [llvm-commits] [llvm] r42908 - in /llvm/trunk: include/llvm/CodeGen/ lib/CodeGen/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/X86/ test/CodeGen/X86/ In-Reply-To: <200710121453.l9CEraSq016799@zion.cs.uiuc.edu> References: <200710121453.l9CEraSq016799@zion.cs.uiuc.edu> Message-ID: <16e5fdf90710121452s36985425r4fe94f1cde3afed8@mail.gmail.com> Hi Dan, With your changes, I'm getting this during bootrapping of llvm-gcc: /var/tmp//cc8ddbeM.s:unknown:Undefined local symbol L0__set_6__run_routines /var/tmp//cc8ddbeM.s:unknown:Undefined local symbol L0__set_9__run_routines /var/tmp//cc8ddbeM.s:unknown:Undefined local symbol L0__set_7__run_routines /var/tmp//cc8ddbeM.s:unknown:Undefined local symbol L0__set_10__run_routines /var/tmp//cc8ddbeM.s:unknown:Undefined local symbol L0__set_8__run_routines /var/tmp//cc8ddbeM.s:unknown:Undefined local symbol L0__set_11__run_routines This is during the build of crt3.o. I think it's due to this part of the patch. > --- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original) > +++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Fri Oct 12 09:53:36 2007 > @@ -306,15 +306,15 @@ > // If we're emitting non-PIC code, then emit the entries as direct > // references to the target basic blocks. > if (!EmittedSets.empty()) { > - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() > - << '_' << i << "_set_" << JTBBs[ii]->getNumber(); > + O << TAI->getPrivateGlobalPrefix() << i > + << '_' << "_set_" << JTBBs[ii]->getNumber() << '_' << CurrentFnName; In particular, this: << '_' << "_set_" ... should probably be: << "_set_" What do you think? -bw From arnold.schwaighofer at gmail.com Fri Oct 12 16:53:13 2007 From: arnold.schwaighofer at gmail.com (Arnold Schwaighofer) Date: Fri, 12 Oct 2007 21:53:13 -0000 Subject: [llvm-commits] [llvm] r42935 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200710122153.l9CLrD3h005643@zion.cs.uiuc.edu> Author: arnolds Date: Fri Oct 12 16:53:12 2007 New Revision: 42935 URL: http://llvm.org/viewvc/llvm-project?rev=42935&view=rev Log: Correcting the corrections. Bad bad baaad emacs! Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=42935&r1=42934&r2=42935&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Oct 12 16:53:12 2007 @@ -1,4 +1,4 @@ -//===-- X86isellowering.cpp - X86 DAG Lowering Implementation -------------===// +//===-- X86ISelLowering.cpp - X86 DAG Lowering Implementation -------------===// // // The LLVM Compiler Infrastructure // From dalej at apple.com Fri Oct 12 17:14:12 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 12 Oct 2007 15:14:12 -0700 Subject: [llvm-commits] [llvm] r42908 - in /llvm/trunk: include/llvm/CodeGen/ lib/CodeGen/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/X86/ test/CodeGen/X86/ In-Reply-To: <16e5fdf90710121452s36985425r4fe94f1cde3afed8@mail.gmail.com> References: <200710121453.l9CEraSq016799@zion.cs.uiuc.edu> <16e5fdf90710121452s36985425r4fe94f1cde3afed8@mail.gmail.com> Message-ID: <862B429F-E004-4DA4-B5E6-4DF922874A38@apple.com> It would be nice if names were only constructed in one place.... On Oct 12, 2007, at 2:52 PM, Bill Wendling wrote: > Hi Dan, > > With your changes, I'm getting this during bootrapping of llvm-gcc: > > /var/tmp//cc8ddbeM.s:unknown:Undefined local symbol > L0__set_6__run_routines > /var/tmp//cc8ddbeM.s:unknown:Undefined local symbol > L0__set_9__run_routines > /var/tmp//cc8ddbeM.s:unknown:Undefined local symbol > L0__set_7__run_routines > /var/tmp//cc8ddbeM.s:unknown:Undefined local symbol > L0__set_10__run_routines > /var/tmp//cc8ddbeM.s:unknown:Undefined local symbol > L0__set_8__run_routines > /var/tmp//cc8ddbeM.s:unknown:Undefined local symbol > L0__set_11__run_routines > > This is during the build of crt3.o. I think it's due to this part > of the patch. > >> --- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original) >> +++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Fri Oct 12 09:53:36 2007 >> @@ -306,15 +306,15 @@ >> // If we're emitting non-PIC code, then emit the entries as >> direct >> // references to the target basic blocks. >> if (!EmittedSets.empty()) { >> - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() >> - << '_' << i << "_set_" << JTBBs[ii]->getNumber(); >> + O << TAI->getPrivateGlobalPrefix() << i >> + << '_' << "_set_" << JTBBs[ii]->getNumber() << '_' << >> CurrentFnName; > > In particular, this: > > << '_' << "_set_" ... > > should probably be: > > << "_set_" > > What do you think? > > -bw > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From asl at math.spbu.ru Fri Oct 12 17:17:41 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sat, 13 Oct 2007 02:17:41 +0400 Subject: [llvm-commits] [llvm] r42908 - in /llvm/trunk: include/llvm/CodeGen/ lib/CodeGen/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/X86/ test/CodeGen/X86/ In-Reply-To: <862B429F-E004-4DA4-B5E6-4DF922874A38.SS1830SS@apple.com> References: <200710121453.l9CEraSq016799@zion.cs.uiuc.edu> <16e5fdf90710121452s36985425r4fe94f1cde3afed8@mail.gmail.com> <862B429F-E004-4DA4-B5E6-4DF922874A38.SS1830SS@apple.com> Message-ID: <1192227461.10271.21.camel@asl.dorms.spbu.ru> > It would be nice if names were only constructed in one place.... I think this is one of the tasks mentioned in PR1650 -- With best regards, Anton Korobeynikov. Faculty of Mathematics & Mechanics, Saint Petersburg State University. From lattner at apple.com Fri Oct 12 17:55:21 2007 From: lattner at apple.com (Tanya Lattner) Date: Fri, 12 Oct 2007 15:55:21 -0700 Subject: [llvm-commits] darwin x86 make check failures In-Reply-To: <20071012204829.GD21991@village.us.cray.com> References: <20071012204829.GD21991@village.us.cray.com> Message-ID: <2CFE6C2E-7A1D-41D0-ABC3-985FDA55FADA@apple.com> Thanks Dale & Dan! The second one passes for me now. -Tanya On Oct 12, 2007, at 1:48 PM, Dan Gohman wrote: >>> Anyone want to claim them? ;) >> >> I confirm this is happening, but it was not happening until I did a >> checkout. > > They're both due to 42908. > >> 2006-10-19-SwitchUnnecessaryBranching.ll was introduced by the change >> in label names. >> It looks like there was an attempt to fix it once, so it's probably >> OS dependent. On darwin >> it's trying to match LBB1__main (2 underscores) with BB1_main (1 >> underscore). > > I'll add a target triple to make this one behave consistently. > >> The other one is failing doing >> grep -i ST | not grep {fadd\\|fsub\\|fdiv\\|fmul} >> >> There are no lines that match ST (correctly IMO). I would expect >> "not grep" to succeed >> on null input, but apparently it doesn't. It's not obvious what the >> grep for ST is trying to >> do, but I doubt this is still testing what it was supposed to test. > > I just submitted a fix for this one. I believe it now tests what > it's supposed to. > > Dan > > -- > Dan Gohman, Cray Inc. > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Fri Oct 12 21:23:02 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 13 Oct 2007 02:23:02 -0000 Subject: [llvm-commits] [llvm] r42945 - in /llvm/trunk: include/llvm/CodeGen/MachineInstr.h lib/CodeGen/MachineInstr.cpp Message-ID: <200710130223.l9D2N2eK016864@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 21:23:01 2007 New Revision: 42945 URL: http://llvm.org/viewvc/llvm-project?rev=42945&view=rev Log: Optionally create a MachineInstr without default implicit operands. Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h llvm/trunk/lib/CodeGen/MachineInstr.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstr.h?rev=42945&r1=42944&r2=42945&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineInstr.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h Fri Oct 12 21:23:01 2007 @@ -340,7 +340,7 @@ /// MachineInstr ctor - This constructor create a MachineInstr and add the /// implicit operands. It reserves space for number of operands specified by /// TargetInstrDescriptor. - explicit MachineInstr(const TargetInstrDescriptor &TID); + explicit MachineInstr(const TargetInstrDescriptor &TID, bool NoImp = false); /// MachineInstr ctor - Work exactly the same as the ctor above, except that /// the MachineInstr is created and added to the end of the specified basic Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=42945&r1=42944&r2=42945&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Fri Oct 12 21:23:01 2007 @@ -58,16 +58,17 @@ /// implicit operands. It reserves space for number of operands specified by /// TargetInstrDescriptor or the numOperands if it is not zero. (for /// instructions with variable number of operands). -MachineInstr::MachineInstr(const TargetInstrDescriptor &tid) +MachineInstr::MachineInstr(const TargetInstrDescriptor &tid, bool NoImp) : TID(&tid), NumImplicitOps(0), parent(0) { - if (TID->ImplicitDefs) + if (!NoImp && TID->ImplicitDefs) for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) NumImplicitOps++; - if (TID->ImplicitUses) + if (!NoImp && TID->ImplicitUses) for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses) NumImplicitOps++; Operands.reserve(NumImplicitOps + TID->numOperands); - addImplicitDefUseOperands(); + if (!NoImp) + addImplicitDefUseOperands(); // Make sure that we get added to a machine basicblock LeakDetector::addGarbageObject(this); } From evan.cheng at apple.com Fri Oct 12 21:35:07 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 13 Oct 2007 02:35:07 -0000 Subject: [llvm-commits] [llvm] r42946 - in /llvm/trunk: include/llvm/Target/MRegisterInfo.h lib/Target/X86/X86RegisterInfo.cpp lib/Target/X86/X86RegisterInfo.h Message-ID: <200710130235.l9D2Z7tl017250@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 21:35:06 2007 New Revision: 42946 URL: http://llvm.org/viewvc/llvm-project?rev=42946&view=rev Log: Change unfoldMemoryOperand(). User is now responsible for passing in the register used by the unfolded instructions. User can also specify whether to unfold the load, the store, or both. Modified: llvm/trunk/include/llvm/Target/MRegisterInfo.h llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp llvm/trunk/lib/Target/X86/X86RegisterInfo.h Modified: llvm/trunk/include/llvm/Target/MRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/MRegisterInfo.h?rev=42946&r1=42945&r2=42946&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/MRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/MRegisterInfo.h Fri Oct 12 21:35:06 2007 @@ -567,7 +567,7 @@ /// a a store or a load and a store into two or more instruction. If this is /// possible, returns true as well as the new instructions by reference. virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, - SSARegMap *RegMap, + unsigned Reg, bool UnfoldLoad, bool UnfoldStore, SmallVector &NewMIs) const{ return false; } Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=42946&r1=42945&r2=42946&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Fri Oct 12 21:35:06 2007 @@ -1118,7 +1118,7 @@ } bool X86RegisterInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, - SSARegMap *RegMap, + unsigned Reg, bool UnfoldLoad, bool UnfoldStore, SmallVector &NewMIs) const { DenseMap >::iterator I = MemOp2RegOpTable.find((unsigned*)MI->getOpcode()); @@ -1128,6 +1128,13 @@ unsigned Index = I->second.second & 0xf; bool HasLoad = I->second.second & (1 << 4); bool HasStore = I->second.second & (1 << 5); + if (UnfoldLoad && !HasLoad) + return false; + HasLoad &= UnfoldLoad; + if (UnfoldStore && !HasStore) + return false; + HasStore &= UnfoldStore; + const TargetInstrDescriptor &TID = TII.get(Opc); const TargetOperandInfo &TOI = TID.OpInfo[Index]; const TargetRegisterClass *RC = (TOI.Flags & M_LOOK_UP_PTR_REG_CLASS) @@ -1149,10 +1156,8 @@ } // Emit the load instruction. - unsigned LoadReg = 0; if (HasLoad) { - LoadReg = RegMap->createVirtualRegister(RC); - loadRegFromAddr(MF, LoadReg, AddrOps, RC, NewMIs); + loadRegFromAddr(MF, Reg, AddrOps, RC, NewMIs); if (HasStore) { // Address operands cannot be marked isKill. for (unsigned i = 1; i != 5; ++i) { @@ -1164,27 +1169,29 @@ } // Emit the data processing instruction. - MachineInstrBuilder MIB = BuildMI(TII.get(Opc)); - unsigned StoreReg = 0; + MachineInstr *DataMI = new MachineInstr (TID, true); + MachineInstrBuilder MIB(DataMI); const TargetRegisterClass *DstRC = 0; if (HasStore) { const TargetOperandInfo &DstTOI = TID.OpInfo[0]; DstRC = (DstTOI.Flags & M_LOOK_UP_PTR_REG_CLASS) ? TII.getPointerRegClass() : getRegClass(DstTOI.RegClass); - StoreReg = RegMap->createVirtualRegister(RC); - MIB.addReg(StoreReg, true); + MIB.addReg(Reg, true); } for (unsigned i = 0, e = BeforeOps.size(); i != e; ++i) MIB = X86InstrAddOperand(MIB, BeforeOps[i]); - if (LoadReg) - MIB.addReg(LoadReg); + MIB.addReg(Reg); for (unsigned i = 0, e = AfterOps.size(); i != e; ++i) MIB = X86InstrAddOperand(MIB, AfterOps[i]); + for (unsigned i = 0, e = ImpOps.size(); i != e; ++i) { + MachineOperand &MO = ImpOps[i]; + MIB.addReg(MO.getReg(), MO.isDef(), true, MO.isKill(), MO.isDead()); + } NewMIs.push_back(MIB); // Emit the store instruction. if (HasStore) - storeRegToAddr(MF, StoreReg, AddrOps, DstRC, NewMIs); + storeRegToAddr(MF, Reg, AddrOps, DstRC, NewMIs); return true; } Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.h?rev=42946&r1=42945&r2=42946&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.h Fri Oct 12 21:35:06 2007 @@ -136,7 +136,7 @@ /// a store or a load and a store into two or more instruction. If this is /// possible, returns true as well as the new instructions by reference. bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, - SSARegMap *RegMap, + unsigned Reg, bool UnfoldLoad, bool UnfoldStore, SmallVector &NewMIs) const; bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, From evan.cheng at apple.com Fri Oct 12 21:50:24 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 13 Oct 2007 02:50:24 -0000 Subject: [llvm-commits] [llvm] r42947 - in /llvm/trunk/lib/CodeGen: VirtRegMap.cpp VirtRegMap.h Message-ID: <200710130250.l9D2oPCb017711@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 21:50:24 2007 New Revision: 42947 URL: http://llvm.org/viewvc/llvm-project?rev=42947&view=rev Log: Local spiller optimization: Turn this: movswl %ax, %eax movl %eax, -36(%ebp) xorl %edi, -36(%ebp) into movswl %ax, %eax xorl %edi, %eax movl %eax, -36(%ebp) by unfolding the load / store xorl into an xorl and a store when we know the value in the spill slot is available in a register. This doesn't change the number of instructions but reduce the number of times memory is accessed. Also unfold some load folding instructions and reuse the value when similar situation presents itself. Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp llvm/trunk/lib/CodeGen/VirtRegMap.h Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=42947&r1=42946&r2=42947&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Fri Oct 12 21:50:24 2007 @@ -139,6 +139,11 @@ MI2VirtMap.insert(IP, std::make_pair(NewMI, std::make_pair(VirtReg, MRInfo))); } +void VirtRegMap::virtFolded(unsigned VirtReg, MachineInstr *MI, ModRef MRInfo) { + MI2VirtMapTy::iterator IP = MI2VirtMap.lower_bound(MI); + MI2VirtMap.insert(IP, std::make_pair(MI, std::make_pair(VirtReg, MRInfo))); +} + void VirtRegMap::print(std::ostream &OS) const { const MRegisterInfo* MRI = MF.getTarget().getRegisterInfo(); @@ -1059,6 +1064,19 @@ Erased = true; goto ProcessNextInst; } + } else { + unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS); + SmallVector NewMIs; + if (PhysReg && + MRI->unfoldMemoryOperand(MF, &MI, PhysReg, false, false, NewMIs)) { + MBB.insert(MII, NewMIs[0]); + VRM.RemoveFromFoldedVirtMap(&MI); + MBB.erase(&MI); + Erased = true; + --NextMII; // backtrack to the unfolded instruction. + BackTracked = true; + goto ProcessNextInst; + } } } @@ -1066,16 +1084,44 @@ // Otherwise, the store to this stack slot is not dead anymore. MachineInstr* DeadStore = MaybeDeadStores[SS]; if (DeadStore) { - if (!(MR & VirtRegMap::isRef)) { // Previous store is dead. + bool isDead = true; + MachineInstr *NewStore = NULL; + if (MR & VirtRegMap::isRef) { + unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS); + SmallVector NewMIs; + if (PhysReg && + DeadStore->findRegisterUseOperandIdx(PhysReg, true) != -1 && + MRI->unfoldMemoryOperand(MF, &MI, PhysReg, false, true, NewMIs)) { + MBB.insert(MII, NewMIs[0]); + NewStore = NewMIs[1]; + MBB.insert(MII, NewStore); + VRM.RemoveFromFoldedVirtMap(&MI); + MBB.erase(&MI); + Erased = true; + --NextMII; + --NextMII; // backtrack to the unfolded instruction. + BackTracked = true; + } else + isDead = false; + } + + if (isDead) { // Previous store is dead. // If we get here, the store is dead, nuke it now. - assert(VirtRegMap::isMod && "Can't be modref!"); DOUT << "Removed dead store:\t" << *DeadStore; InvalidateKills(*DeadStore, RegKills, KillOps); - MBB.erase(DeadStore); VRM.RemoveFromFoldedVirtMap(DeadStore); - ++NumDSE; + MBB.erase(DeadStore); + if (!NewStore) + ++NumDSE; } + MaybeDeadStores[SS] = NULL; + if (NewStore) { + // Treat this store as a spill merged into a copy. That makes the + // stack slot value available. + VRM.virtFolded(VirtReg, NewStore, VirtRegMap::isMod); + goto ProcessNextInst; + } } // If the spill slot value is available, and this is a new definition of Modified: llvm/trunk/lib/CodeGen/VirtRegMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.h?rev=42947&r1=42946&r2=42947&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.h (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.h Fri Oct 12 21:50:24 2007 @@ -181,6 +181,10 @@ void virtFolded(unsigned VirtReg, MachineInstr *OldMI, unsigned OpNum, MachineInstr *NewMI); + /// @brief Updates information about the specified virtual register's value + /// folded into the specified machine instruction. + void virtFolded(unsigned VirtReg, MachineInstr *MI, ModRef MRInfo); + /// @brief returns the virtual registers' values folded in memory /// operands of this instruction std::pair From evan.cheng at apple.com Fri Oct 12 22:10:54 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 13 Oct 2007 03:10:54 -0000 Subject: [llvm-commits] [llvm] r42948 - in /llvm/trunk/test/CodeGen/X86: 2007-10-12-SpillerUnfold1.ll 2007-10-12-SpillerUnfold2.ll Message-ID: <200710130310.l9D3Atge018333@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 22:10:54 2007 New Revision: 42948 URL: http://llvm.org/viewvc/llvm-project?rev=42948&view=rev Log: New tests. Added: llvm/trunk/test/CodeGen/X86/2007-10-12-SpillerUnfold1.ll llvm/trunk/test/CodeGen/X86/2007-10-12-SpillerUnfold2.ll Added: llvm/trunk/test/CodeGen/X86/2007-10-12-SpillerUnfold1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-10-12-SpillerUnfold1.ll?rev=42948&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-10-12-SpillerUnfold1.ll (added) +++ llvm/trunk/test/CodeGen/X86/2007-10-12-SpillerUnfold1.ll Fri Oct 12 22:10:54 2007 @@ -0,0 +1,45 @@ +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep addss | not grep esp + +define fastcc void @fht(float* %fz, i16 signext %n) { +entry: + br i1 true, label %bb171.preheader, label %bb431 + +bb171.preheader: ; preds = %entry + %tmp176 = add float 0.000000e+00, 1.000000e+00 ; [#uses=2] + %gi.1 = getelementptr float* %fz, i32 0 ; [#uses=2] + %tmp240 = load float* %gi.1, align 4 ; [#uses=1] + %tmp242 = sub float %tmp240, 0.000000e+00 ; [#uses=2] + %tmp251 = getelementptr float* %fz, i32 0 ; [#uses=1] + %tmp252 = load float* %tmp251, align 4 ; [#uses=1] + %tmp258 = getelementptr float* %fz, i32 0 ; [#uses=2] + %tmp259 = load float* %tmp258, align 4 ; [#uses=2] + %tmp261 = mul float %tmp259, %tmp176 ; [#uses=1] + %tmp262 = sub float 0.000000e+00, %tmp261 ; [#uses=2] + %tmp269 = mul float %tmp252, %tmp176 ; [#uses=1] + %tmp276 = mul float %tmp259, 0.000000e+00 ; [#uses=1] + %tmp277 = add float %tmp269, %tmp276 ; [#uses=2] + %tmp281 = getelementptr float* %fz, i32 0 ; [#uses=1] + %tmp282 = load float* %tmp281, align 4 ; [#uses=2] + %tmp284 = sub float %tmp282, %tmp277 ; [#uses=1] + %tmp291 = add float %tmp282, %tmp277 ; [#uses=1] + %tmp298 = sub float 0.000000e+00, %tmp262 ; [#uses=1] + %tmp305 = add float 0.000000e+00, %tmp262 ; [#uses=1] + %tmp315 = mul float 0.000000e+00, %tmp291 ; [#uses=1] + %tmp318 = mul float 0.000000e+00, %tmp298 ; [#uses=1] + %tmp319 = add float %tmp315, %tmp318 ; [#uses=1] + %tmp329 = add float 0.000000e+00, %tmp319 ; [#uses=1] + store float %tmp329, float* null, align 4 + %tmp336 = sub float %tmp242, 0.000000e+00 ; [#uses=1] + store float %tmp336, float* %tmp258, align 4 + %tmp343 = add float %tmp242, 0.000000e+00 ; [#uses=1] + store float %tmp343, float* null, align 4 + %tmp355 = mul float 0.000000e+00, %tmp305 ; [#uses=1] + %tmp358 = mul float 0.000000e+00, %tmp284 ; [#uses=1] + %tmp359 = add float %tmp355, %tmp358 ; [#uses=1] + %tmp369 = add float 0.000000e+00, %tmp359 ; [#uses=1] + store float %tmp369, float* %gi.1, align 4 + ret void + +bb431: ; preds = %entry + ret void +} Added: llvm/trunk/test/CodeGen/X86/2007-10-12-SpillerUnfold2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-10-12-SpillerUnfold2.ll?rev=42948&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-10-12-SpillerUnfold2.ll (added) +++ llvm/trunk/test/CodeGen/X86/2007-10-12-SpillerUnfold2.ll Fri Oct 12 22:10:54 2007 @@ -0,0 +1,57 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep sarl | not grep esp + +define i16 @t(i16* %qmatrix, i16* %dct, i16* %acBaseTable, i16* %acExtTable, i16 signext %acBaseRes, i16 signext %acMaskRes, i16 signext %acExtRes, i32* %bitptr, i32* %source, i32 %markerPrefix, i8** %byteptr, i32 %scale, i32 %round, i32 %bits) signext { +entry: + br label %cond_next127 + +cond_next127: ; preds = %cond_next391, %entry + %tmp151 = add i32 0, %round ; [#uses=1] + %tmp153 = ashr i32 %tmp151, %scale ; [#uses=1] + %tmp158 = xor i32 0, %tmp153 ; [#uses=1] + %tmp160 = or i32 %tmp158, 0 ; [#uses=1] + %tmp180181 = sext i16 0 to i32 ; [#uses=1] + %tmp183 = add i32 %tmp160, 1 ; [#uses=1] + br i1 false, label %cond_true188, label %cond_next245 + +cond_true188: ; preds = %cond_next127 + ret i16 0 + +cond_next245: ; preds = %cond_next127 + %tmp253444 = lshr i32 %tmp180181, 4 ; [#uses=1] + %tmp254 = and i32 %tmp253444, 15 ; [#uses=1] + br i1 false, label %cond_true267, label %cond_next391 + +cond_true267: ; preds = %cond_next245 + %tmp269 = load i8** %byteptr, align 4 ; [#uses=3] + %tmp270 = load i8* %tmp269, align 1 ; [#uses=1] + %tmp270271 = zext i8 %tmp270 to i32 ; [#uses=1] + %tmp272 = getelementptr i8* %tmp269, i32 1 ; [#uses=2] + store i8* %tmp272, i8** %byteptr, align 4 + %tmp276 = load i8* %tmp272, align 1 ; [#uses=1] + %tmp278 = getelementptr i8* %tmp269, i32 2 ; [#uses=1] + store i8* %tmp278, i8** %byteptr, align 4 + %tmp286 = icmp eq i32 %tmp270271, %markerPrefix ; [#uses=1] + %cond = icmp eq i8 %tmp276, 0 ; [#uses=1] + %bothcond = and i1 %tmp286, %cond ; [#uses=1] + br i1 %bothcond, label %cond_true294, label %cond_next327 + +cond_true294: ; preds = %cond_true267 + ret i16 0 + +cond_next327: ; preds = %cond_true267 + br i1 false, label %cond_true343, label %cond_next391 + +cond_true343: ; preds = %cond_next327 + %tmp345 = load i8** %byteptr, align 4 ; [#uses=1] + store i8* null, i8** %byteptr, align 4 + store i8* %tmp345, i8** %byteptr, align 4 + br label %cond_next391 + +cond_next391: ; preds = %cond_true343, %cond_next327, %cond_next245 + %tmp422445 = add i32 %tmp254, %tmp183 ; [#uses=1] + %tmp429448 = icmp ult i32 %tmp422445, 63 ; [#uses=1] + br i1 %tmp429448, label %cond_next127, label %UnifiedReturnBlock + +UnifiedReturnBlock: ; preds = %cond_next391 + ret i16 0 +} From evan.cheng at apple.com Fri Oct 12 22:14:06 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 13 Oct 2007 03:14:06 -0000 Subject: [llvm-commits] [llvm] r42949 - /llvm/trunk/test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll Message-ID: <200710130314.l9D3E6d8018421@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 12 22:14:06 2007 New Revision: 42949 URL: http://llvm.org/viewvc/llvm-project?rev=42949&view=rev Log: Fix test case. Modified: llvm/trunk/test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll Modified: llvm/trunk/test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll?rev=42949&r1=42948&r2=42949&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll (original) +++ llvm/trunk/test/CodeGen/X86/2006-10-19-SwitchUnnecessaryBranching.ll Fri Oct 12 22:14:06 2007 @@ -1,5 +1,5 @@ ; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86 | %prcontext je 1 | \ -; RUN: grep BB1_main: +; RUN: grep BB | grep main %str = internal constant [14 x sbyte] c"Hello world!\0A\00" ; <[14 x sbyte]*> [#uses=1] %str = internal constant [13 x sbyte] c"Blah world!\0A\00" ; <[13 x sbyte]*> [#uses=1] From neil at daikokuya.co.uk Fri Oct 12 22:34:08 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Sat, 13 Oct 2007 03:34:08 -0000 Subject: [llvm-commits] [llvm] r42950 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200710130334.l9D3Y8pm019033@zion.cs.uiuc.edu> Author: neil Date: Fri Oct 12 22:34:08 2007 New Revision: 42950 URL: http://llvm.org/viewvc/llvm-project?rev=42950&view=rev Log: If the power of 5 is exact, and the reciprocal exact, the error is zero not one half-ulps. This prevents an infinite loop in rare cases. Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=42950&r1=42949&r2=42950&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Fri Oct 12 22:34:08 2007 @@ -1947,7 +1947,7 @@ excessPrecision = calcSemantics.precision; } /* Extra half-ulp lost in reciprocal of exponent. */ - powHUerr = 1 + powStatus != opOK; + powHUerr = (powStatus == opOK && calcLostFraction == lfExactlyZero) ? 0: 2; } /* Both multiplySignificand and divideSignificand return the From clattner at apple.com Sat Oct 13 00:22:34 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 12 Oct 2007 22:22:34 -0700 Subject: [llvm-commits] [llvm] r42930 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <200710122010.l9CKALGj032645@zion.cs.uiuc.edu> References: <200710122010.l9CKALGj032645@zion.cs.uiuc.edu> Message-ID: On Oct 12, 2007, at 1:10 PM, Devang Patel wrote: > + // Destination pointer type is always i8 * > + if (Size == 8) > + NewPtrTy = PointerType::get(Type::Int64Ty); > + else if (Size == 4) > + NewPtrTy = PointerType::get(Type::Int32Ty); > + else if (Size == 2) > + NewPtrTy = PointerType::get(Type::Int16Ty); > + else if (Size == 1) > + NewPtrTy = PointerType::get(Type::Int8Ty); How about: if (Size && Size <= 8 && (Size&(Size-1))) NewPtrTy = PointerType::get(IntegerType::get(Size)); If you don't like "(Size&(Size-1)", use MathExtras.h isPow2 methods. Thanks Devang, -Chris From sabre at nondot.org Sat Oct 13 01:35:55 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 13 Oct 2007 06:35:55 -0000 Subject: [llvm-commits] [llvm] r42952 - in /llvm/trunk/lib/CodeGen/SelectionDAG: DAGCombiner.cpp LegalizeDAG.cpp Message-ID: <200710130635.l9D6ZtcW023926@zion.cs.uiuc.edu> Author: lattner Date: Sat Oct 13 01:35:54 2007 New Revision: 42952 URL: http://llvm.org/viewvc/llvm-project?rev=42952&view=rev Log: Add a simple optimization to simplify the input to truncate and truncstore instructions, based on the knowledge that they don't demand the top bits. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=42952&r1=42951&r2=42952&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sat Oct 13 01:35:54 2007 @@ -295,6 +295,8 @@ SDNode *MatchRotate(SDOperand LHS, SDOperand RHS); SDOperand ReduceLoadWidth(SDNode *N); + SDOperand GetDemandedBits(SDOperand V, uint64_t Mask); + /// GatherAllAliases - Walk up chain skipping non-aliasing memory nodes, /// looking for aliasing nodes and adding them to the Aliases vector. void GatherAllAliases(SDNode *N, SDOperand OriginalChain, @@ -2793,6 +2795,24 @@ return SDOperand(); } +/// GetDemandedBits - See if the specified operand can be simplified with the +/// knowledge that only the bits specified by Mask are used. If so, return the +/// simpler operand, otherwise return a null SDOperand. +SDOperand DAGCombiner::GetDemandedBits(SDOperand V, uint64_t Mask) { + switch (V.getOpcode()) { + default: break; + case ISD::OR: + case ISD::XOR: + // If the LHS or RHS don't contribute bits to the or, drop them. + if (DAG.MaskedValueIsZero(V.getOperand(0), Mask)) + return V.getOperand(1); + if (DAG.MaskedValueIsZero(V.getOperand(1), Mask)) + return V.getOperand(0); + break; + } + return SDOperand(); +} + /// ReduceLoadWidth - If the result of a wider load is shifted to right of N /// bits and then truncated to a narrower type and where N is a multiple /// of number of bits of the narrower type, transform it to a narrower load @@ -2986,6 +3006,13 @@ return N0.getOperand(0); } + // See if we can simplify the input to this truncate through knowledge that + // only the low bits are being used. For example "trunc (or (shl x, 8), y)" + // -> trunc y + SDOperand Shorter = GetDemandedBits(N0, MVT::getIntVTBitMask(VT)); + if (Shorter.Val) + return DAG.getNode(ISD::TRUNCATE, VT, Shorter); + // fold (truncate (load x)) -> (smaller load x) // fold (truncate (srl (load x), c)) -> (smaller load (x+c/evtbits)) return ReduceLoadWidth(N); @@ -4000,6 +4027,21 @@ if (CombineToPreIndexedLoadStore(N) || CombineToPostIndexedLoadStore(N)) return SDOperand(N, 0); + // FIXME: is there such a think as a truncating indexed store? + if (ST->isTruncatingStore() && ST->getAddressingMode() == ISD::UNINDEXED && + MVT::isInteger(Value.getValueType())) { + // See if we can simplify the input to this truncstore with knowledge that + // only the low bits are being used. For example: + // "truncstore (or (shl x, 8), y), i8" -> "truncstore y, i8" + SDOperand Shorter = + GetDemandedBits(Value, MVT::getIntVTBitMask(ST->getStoredVT())); + AddToWorkList(Value.Val); + if (Shorter.Val) + return DAG.getTruncStore(Chain, Shorter, Ptr, ST->getSrcValue(), + ST->getSrcValueOffset(), ST->getStoredVT(), + ST->isVolatile(), ST->getAlignment()); + } + return SDOperand(); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=42952&r1=42951&r2=42952&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat Oct 13 01:35:54 2007 @@ -2025,7 +2025,7 @@ // probably means that we need to integrate dag combiner and legalizer // together. // We generally can't do this one for long doubles. - if (ConstantFPSDNode *CFP =dyn_cast(ST->getValue())) { + if (ConstantFPSDNode *CFP = dyn_cast(ST->getValue())) { if (CFP->getValueType(0) == MVT::f32) { Tmp3 = DAG.getConstant((uint32_t)CFP->getValueAPF(). convertToAPInt().getZExtValue(), From sabre at nondot.org Sat Oct 13 01:56:19 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 13 Oct 2007 06:56:19 -0000 Subject: [llvm-commits] [llvm] r42953 - /llvm/trunk/test/CodeGen/ARM/truncstore-dag-combine.ll Message-ID: <200710130656.l9D6uJql024522@zion.cs.uiuc.edu> Author: lattner Date: Sat Oct 13 01:56:18 2007 New Revision: 42953 URL: http://llvm.org/viewvc/llvm-project?rev=42953&view=rev Log: new testcase Added: llvm/trunk/test/CodeGen/ARM/truncstore-dag-combine.ll Added: llvm/trunk/test/CodeGen/ARM/truncstore-dag-combine.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/truncstore-dag-combine.ll?rev=42953&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/truncstore-dag-combine.ll (added) +++ llvm/trunk/test/CodeGen/ARM/truncstore-dag-combine.ll Sat Oct 13 01:56:18 2007 @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | llc -march=arm | not grep orr +; RUN: llvm-as < %s | llc -march=arm | not grep mov + +define void @bar(i8* %P, i16* %Q) { +entry: + %P1 = bitcast i8* %P to i16* ; [#uses=1] + %tmp = load i16* %Q, align 1 ; [#uses=1] + store i16 %tmp, i16* %P1, align 1 + ret void +} + +define void @foo(i8* %P, i32* %Q) { +entry: + %P1 = bitcast i8* %P to i32* ; [#uses=1] + %tmp = load i32* %Q, align 1 ; [#uses=1] + store i32 %tmp, i32* %P1, align 1 + ret void +} From sabre at nondot.org Sat Oct 13 01:58:48 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 13 Oct 2007 06:58:48 -0000 Subject: [llvm-commits] [llvm] r42954 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200710130658.l9D6wmBB024589@zion.cs.uiuc.edu> Author: lattner Date: Sat Oct 13 01:58:48 2007 New Revision: 42954 URL: http://llvm.org/viewvc/llvm-project?rev=42954&view=rev Log: Enhance the truncstore optimization code to handle shifted values and propagate demanded bits through them in simple cases. This allows this code: void foo(char *P) { strcpy(P, "abc"); } to compile to: _foo: ldrb r3, [r1] ldrb r2, [r1, #+1] ldrb r12, [r1, #+2]! ldrb r1, [r1, #+1] strb r1, [r0, #+3] strb r2, [r0, #+1] strb r12, [r0, #+2] strb r3, [r0] bx lr instead of: _foo: ldrb r3, [r1, #+3] ldrb r2, [r1, #+2] orr r3, r2, r3, lsl #8 ldrb r2, [r1, #+1] ldrb r1, [r1] orr r2, r1, r2, lsl #8 orr r3, r2, r3, lsl #16 strb r3, [r0] mov r2, r3, lsr #24 strb r2, [r0, #+3] mov r2, r3, lsr #16 strb r2, [r0, #+2] mov r3, r3, lsr #8 strb r3, [r0, #+1] bx lr testcase here: test/CodeGen/ARM/truncstore-dag-combine.ll This also helps occasionally for X86 and other cases not involving unaligned load/stores. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=42954&r1=42953&r2=42954&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sat Oct 13 01:58:48 2007 @@ -156,10 +156,10 @@ /// SimplifyDemandedBits - Check the specified integer node value to see if /// it can be simplified or if things it uses can be simplified by bit /// propagation. If so, return true. - bool SimplifyDemandedBits(SDOperand Op) { + bool SimplifyDemandedBits(SDOperand Op, uint64_t Demanded = ~0ULL) { TargetLowering::TargetLoweringOpt TLO(DAG); uint64_t KnownZero, KnownOne; - uint64_t Demanded = MVT::getIntVTBitMask(Op.getValueType()); + Demanded &= MVT::getIntVTBitMask(Op.getValueType()); if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne, TLO)) return false; @@ -2809,6 +2809,20 @@ if (DAG.MaskedValueIsZero(V.getOperand(1), Mask)) return V.getOperand(0); break; + case ISD::SRL: + // Only look at single-use SRLs. + if (!V.Val->hasOneUse()) + break; + if (ConstantSDNode *RHSC = dyn_cast(V.getOperand(1))) { + // See if we can recursively simplify the LHS. + unsigned Amt = RHSC->getValue(); + Mask = (Mask << Amt) & MVT::getIntVTBitMask(V.getValueType()); + SDOperand SimplifyLHS = GetDemandedBits(V.getOperand(0), Mask); + if (SimplifyLHS.Val) { + return DAG.getNode(ISD::SRL, V.getValueType(), + SimplifyLHS, V.getOperand(1)); + } + } } return SDOperand(); } @@ -4040,6 +4054,11 @@ return DAG.getTruncStore(Chain, Shorter, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->getStoredVT(), ST->isVolatile(), ST->getAlignment()); + + // Otherwise, see if we can simplify the operation with + // SimplifyDemandedBits, which only works if the value has a single use. + if (SimplifyDemandedBits(Value, MVT::getIntVTBitMask(ST->getStoredVT()))) + return SDOperand(N, 0); } return SDOperand(); From baldrick at free.fr Sat Oct 13 02:38:38 2007 From: baldrick at free.fr (Duncan Sands) Date: Sat, 13 Oct 2007 07:38:38 -0000 Subject: [llvm-commits] [llvm] r42955 - /llvm/trunk/lib/Target/X86/X86CallingConv.td Message-ID: <200710130738.l9D7cci6029927@zion.cs.uiuc.edu> Author: baldrick Date: Sat Oct 13 02:38:37 2007 New Revision: 42955 URL: http://llvm.org/viewvc/llvm-project?rev=42955&view=rev Log: Clarify that fastcc has a problem with nested function trampolines, rather than with nested functions themselves. Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallingConv.td?rev=42955&r1=42954&r2=42955&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CallingConv.td (original) +++ llvm/trunk/lib/Target/X86/X86CallingConv.td Sat Oct 13 02:38:37 2007 @@ -213,7 +213,7 @@ // Promote i8/i16 arguments to i32. CCIfType<[i8, i16], CCPromoteToType>, - // Nested functions are currently not supported by fastcc. + // Nested function trampolines are currently not supported by fastcc. // The first 3 integer arguments, if marked 'inreg' and if the call is not // a vararg call, are passed in integer registers. From gordonhenriksen at mac.com Sat Oct 13 19:34:54 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sun, 14 Oct 2007 00:34:54 -0000 Subject: [llvm-commits] [llvm] r42956 - /llvm/trunk/docs/LangRef.html Message-ID: <200710140034.l9E0Ys74006126@zion.cs.uiuc.edu> Author: gordon Date: Sat Oct 13 19:34:53 2007 New Revision: 42956 URL: http://llvm.org/viewvc/llvm-project?rev=42956&view=rev Log: Fixing a typo. Found by Kevin Andr?! Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=42956&r1=42955&r2=42956&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Sat Oct 13 19:34:53 2007 @@ -1296,7 +1296,7 @@
    Overview:

    Opaque types are used to represent unknown types in the system. This -corresponds (for example) to the C notion of a foward declared structure type. +corresponds (for example) to the C notion of a forward declared structure type. In LLVM, opaque types can eventually be resolved to any type (not just a structure type).

    From dalej at apple.com Sat Oct 13 20:56:47 2007 From: dalej at apple.com (Dale Johannesen) Date: Sun, 14 Oct 2007 01:56:47 -0000 Subject: [llvm-commits] [llvm] r42958 - in /llvm/trunk/lib: CodeGen/SelectionDAG/SelectionDAG.cpp VMCore/ConstantFold.cpp Message-ID: <200710140156.l9E1ul3g008577@zion.cs.uiuc.edu> Author: johannes Date: Sat Oct 13 20:56:47 2007 New Revision: 42958 URL: http://llvm.org/viewvc/llvm-project?rev=42958&view=rev Log: Disable some compile-time optimizations on PPC long double. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/VMCore/ConstantFold.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=42958&r1=42957&r2=42958&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Oct 13 20:56:47 2007 @@ -965,6 +965,9 @@ } if (ConstantFPSDNode *N1C = dyn_cast(N1.Val)) if (ConstantFPSDNode *N2C = dyn_cast(N2.Val)) { + // No compile time operations on this type yet. + if (N1C->getValueType(0) == MVT::ppcf128) + return SDOperand(); APFloat::cmpResult R = N1C->getValueAPF().compare(N2C->getValueAPF()); switch (Cond) { Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=42958&r1=42957&r2=42958&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ConstantFold.cpp (original) +++ llvm/trunk/lib/VMCore/ConstantFold.cpp Sat Oct 13 20:56:47 2007 @@ -149,6 +149,9 @@ return Constant::getNullValue(DestTy); return UndefValue::get(DestTy); } + // No compile-time operations on this type yet. + if (V->getType() == Type::PPC_FP128Ty || DestTy == Type::PPC_FP128Ty) + return 0; // If the cast operand is a constant expression, there's a few things we can // do to try to simplify it. @@ -808,6 +811,11 @@ const Constant *V2) { assert(V1->getType() == V2->getType() && "Cannot compare values of different types!"); + + // No compile-time operations on this type yet. + if (V1->getType() == Type::PPC_FP128Ty) + return FCmpInst::BAD_FCMP_PREDICATE; + // Handle degenerate case quickly if (V1 == V2) return FCmpInst::FCMP_OEQ; @@ -1095,6 +1103,10 @@ if (isa(C1) || isa(C2)) return UndefValue::get(Type::Int1Ty); + // No compile-time operations on this type yet. + if (C1->getType() == Type::PPC_FP128Ty) + return 0; + // icmp eq/ne(null,GV) -> false/true if (C1->isNullValue()) { if (const GlobalValue *GV = dyn_cast(C2)) From dalej at apple.com Sat Oct 13 20:58:32 2007 From: dalej at apple.com (Dale Johannesen) Date: Sun, 14 Oct 2007 01:58:32 -0000 Subject: [llvm-commits] [llvm] r42959 - /llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200710140158.l9E1wWPr008632@zion.cs.uiuc.edu> Author: johannes Date: Sat Oct 13 20:58:32 2007 New Revision: 42959 URL: http://llvm.org/viewvc/llvm-project?rev=42959&view=rev Log: Fix type mismatch error in PPC Altivec (only causes a problem when asserts are on). From vecLib. Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=42959&r1=42958&r2=42959&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Sat Oct 13 20:58:32 2007 @@ -2570,14 +2570,14 @@ if (SextVal >= 0 && SextVal <= 31) { SDOperand LHS = BuildSplatI(SextVal-16, SplatSize, MVT::Other, DAG); SDOperand RHS = BuildSplatI(-16, SplatSize, MVT::Other, DAG); - LHS = DAG.getNode(ISD::SUB, Op.getValueType(), LHS, RHS); + LHS = DAG.getNode(ISD::SUB, LHS.getValueType(), LHS, RHS); return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), LHS); } // Odd, in range [-31,-17]: (vsplti C)+(vsplti -16). if (SextVal >= -31 && SextVal <= 0) { SDOperand LHS = BuildSplatI(SextVal+16, SplatSize, MVT::Other, DAG); SDOperand RHS = BuildSplatI(-16, SplatSize, MVT::Other, DAG); - LHS = DAG.getNode(ISD::ADD, Op.getValueType(), LHS, RHS); + LHS = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS); return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), LHS); } } From evan.cheng at apple.com Sun Oct 14 00:48:15 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 13 Oct 2007 22:48:15 -0700 Subject: [llvm-commits] [llvm] r42908 - in /llvm/trunk: include/llvm/CodeGen/ lib/CodeGen/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/X86/ test/CodeGen/X86/ In-Reply-To: <200710121453.l9CEraSq016799@zion.cs.uiuc.edu> References: <200710121453.l9CEraSq016799@zion.cs.uiuc.edu> Message-ID: Hi Dan, I have to back out this patch for now. It's causing a lot of x86-64 / Darwin (also possibly ARM / Darwin) compilation errors. Please investigate. Thanks! Evan On Oct 12, 2007, at 7:53 AM, Dan Gohman wrote: > Author: djg > Date: Fri Oct 12 09:53:36 2007 > New Revision: 42908 > > URL: http://llvm.org/viewvc/llvm-project?rev=42908&view=rev > Log: > Change the names used for internal labels to use the current > function symbol name instead of a codegen-assigned function > number. > > Thanks Evan! :-) > > Modified: > llvm/trunk/include/llvm/CodeGen/AsmPrinter.h > llvm/trunk/lib/CodeGen/AsmPrinter.cpp > llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp > llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp > llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp > llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp > llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp > llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp > llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp > llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp > llvm/trunk/test/CodeGen/X86/2006-10-19- > SwitchUnnecessaryBranching.ll > llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll > llvm/trunk/test/CodeGen/X86/fp_constant_op.llx > > Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ > CodeGen/AsmPrinter.h?rev=42908&r1=42907&r2=42908&view=diff > > ====================================================================== > ======== > --- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original) > +++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Fri Oct 12 > 09:53:36 2007 > @@ -36,13 +36,6 @@ > class AsmPrinter : public MachineFunctionPass { > static char ID; > > - /// FunctionNumber - This provides a unique ID for each > function emitted in > - /// this translation unit. It is autoincremented by > SetupMachineFunction, > - /// and can be accessed with getFunctionNumber() and > - /// IncrementFunctionNumber(). > - /// > - unsigned FunctionNumber; > - > protected: > // Necessary for external weak linkage support > std::set ExtWeakSymbols; > @@ -160,15 +153,6 @@ > /// is being processed from runOnMachineFunction. > void SetupMachineFunction(MachineFunction &MF); > > - /// getFunctionNumber - Return a unique ID for the current > function. > - /// > - unsigned getFunctionNumber() const { return FunctionNumber; } > - > - /// IncrementFunctionNumber - Increase Function Number. > AsmPrinters should > - /// not normally call this, as the counter is automatically > bumped by > - /// SetupMachineFunction. > - void IncrementFunctionNumber() { FunctionNumber++; } > - > /// EmitConstantPool - Print to the current output stream > assembly > /// representations of the constants in the constant pool MCP. > This is > /// used to print out constants which have been "spilled to > memory" by > > Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ > AsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original) > +++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Fri Oct 12 09:53:36 2007 > @@ -35,7 +35,7 @@ > char AsmPrinter::ID = 0; > AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm, > const TargetAsmInfo *T) > - : MachineFunctionPass((intptr_t)&ID), FunctionNumber(0), O(o), TM > (tm), TAI(T) > + : MachineFunctionPass((intptr_t)&ID), O(o), TM(tm), TAI(T) > {} > > std::string AsmPrinter::getSectionForFunction(const Function &F) > const { > @@ -169,7 +169,6 @@ > void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { > // What's my mangled name? > CurrentFnName = Mang->getValueName(MF.getFunction()); > - IncrementFunctionNumber(); > } > > /// EmitConstantPool - Print to the current output stream assembly > @@ -219,8 +218,9 @@ > SwitchToDataSection(Section); > EmitAlignment(Alignment); > for (unsigned i = 0, e = CP.size(); i != e; ++i) { > - O << TAI->getPrivateGlobalPrefix() << "CPI" << > getFunctionNumber() << '_' > - << CP[i].second << ":\t\t\t\t\t" << TAI->getCommentString() > << " "; > + O << TAI->getPrivateGlobalPrefix() << "CPI" << CP[i].second > + << '_' << CurrentFnName > + << ":\t\t\t\t\t" << TAI->getCommentString() << ' '; > WriteTypeSymbolic(O, CP[i].first.getType(), 0) << '\n'; > if (CP[i].first.isMachineConstantPoolEntry()) > EmitMachineConstantPoolValue(CP[i].first.Val.MachineCPVal); > @@ -293,10 +293,10 @@ > // the assembler and linker the extents of the jump table > object. The > // second label is actually referenced by the code. > if (const char *JTLabelPrefix = TAI- > >getJumpTableSpecialLabelPrefix()) > - O << JTLabelPrefix << "JTI" << getFunctionNumber() << '_' << > i << ":\n"; > + O << JTLabelPrefix << "JTI" << i << '_' << CurrentFnName << > ":\n"; > > - O << TAI->getPrivateGlobalPrefix() << "JTI" << > getFunctionNumber() > - << '_' << i << ":\n"; > + O << TAI->getPrivateGlobalPrefix() << "JTI" << i > + << '_' << CurrentFnName << ":\n"; > > for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { > O << JTEntryDirective << ' '; > @@ -306,15 +306,15 @@ > // If we're emitting non-PIC code, then emit the entries as > direct > // references to the target basic blocks. > if (!EmittedSets.empty()) { > - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() > - << '_' << i << "_set_" << JTBBs[ii]->getNumber(); > + O << TAI->getPrivateGlobalPrefix() << i > + << '_' << "_set_" << JTBBs[ii]->getNumber() << '_' << > CurrentFnName; > } else if (IsPic) { > printBasicBlockLabel(JTBBs[ii], false, false); > // If the arch uses custom Jump Table directives, don't > calc relative to > // JT > if (!HadJTEntryDirective) > O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" > - << getFunctionNumber() << '_' << i; > + << i << '_' << CurrentFnName; > } else { > printBasicBlockLabel(JTBBs[ii], false, false); > } > @@ -1242,8 +1242,8 @@ > void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB, > bool printColon, > bool printComment) const { > - O << TAI->getPrivateGlobalPrefix() << "BB" << getFunctionNumber > () << "_" > - << MBB->getNumber(); > + O << TAI->getPrivateGlobalPrefix() << "BB" << MBB->getNumber() > << '_' > + << CurrentFnName; > if (printColon) > O << ':'; > if (printComment && MBB->getBasicBlock()) > @@ -1259,10 +1259,10 @@ > return; > > O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() > - << getFunctionNumber() << '_' << uid << "_set_" << MBB- > >getNumber() << ','; > + << uid << "_set_" << MBB->getNumber() << '_' << CurrentFnName > << ','; > printBasicBlockLabel(MBB, false, false); > - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << > getFunctionNumber() > - << '_' << uid << '\n'; > + O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << uid > + << '_' << CurrentFnName << '\n'; > } > > void AsmPrinter::printSetLabel(unsigned uid, unsigned uid2, > @@ -1271,11 +1271,11 @@ > return; > > O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() > - << getFunctionNumber() << '_' << uid << '_' << uid2 > - << "_set_" << MBB->getNumber() << ','; > + << uid << '_' << uid2 > + << "_set_" << MBB->getNumber() << '_' << CurrentFnName << ','; > printBasicBlockLabel(MBB, false, false); > - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << > getFunctionNumber() > - << '_' << uid << '_' << uid2 << '\n'; > + O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << uid > + << '_' << uid2 << '_' << CurrentFnName << '\n'; > } > > /// printDataDirective - This method prints the asm directive for the > > Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ > ARMAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Fri Oct 12 09:53:36 > 2007 > @@ -319,12 +319,12 @@ > break; > } > case MachineOperand::MO_ConstantPoolIndex: > - O << TAI->getPrivateGlobalPrefix() << "CPI" << > getFunctionNumber() > - << '_' << MO.getConstantPoolIndex(); > + O << TAI->getPrivateGlobalPrefix() << "CPI" << > MO.getConstantPoolIndex() > + << '_' << CurrentFnName; > break; > case MachineOperand::MO_JumpTableIndex: > - O << TAI->getPrivateGlobalPrefix() << "JTI" << > getFunctionNumber() > - << '_' << MO.getJumpTableIndex(); > + O << TAI->getPrivateGlobalPrefix() << "JTI" << > MO.getJumpTableIndex() > + << '_' << CurrentFnName; > break; > default: > O << ""; abort (); break; > @@ -652,8 +652,8 @@ > // data itself. > if (!strcmp(Modifier, "label")) { > unsigned ID = MI->getOperand(OpNo).getImm(); > - O << TAI->getPrivateGlobalPrefix() << "CPI" << > getFunctionNumber() > - << '_' << ID << ":\n"; > + O << TAI->getPrivateGlobalPrefix() << "CPI" << ID > + << '_' << CurrentFnName << ":\n"; > } else { > assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for > CPE"); > unsigned CPI = MI->getOperand(OpNo).getConstantPoolIndex(); > @@ -677,8 +677,8 @@ > const MachineOperand &MO1 = MI->getOperand(OpNo); > const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id > unsigned JTI = MO1.getJumpTableIndex(); > - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() > - << '_' << JTI << '_' << MO2.getImmedValue() << ":\n"; > + O << TAI->getPrivateGlobalPrefix() << "JTI" << JTI > + << '_' << MO2.getImmedValue() << '_' << CurrentFnName << ":\n"; > > const char *JTEntryDirective = TAI->getJumpTableDirective(); > if (!JTEntryDirective) > @@ -697,15 +697,16 @@ > > O << JTEntryDirective << ' '; > if (UseSet) > - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() > - << '_' << JTI << '_' << MO2.getImmedValue() > - << "_set_" << MBB->getNumber(); > + O << TAI->getPrivateGlobalPrefix() << JTI > + << '_' << MO2.getImmedValue() > + << "_set_" << MBB->getNumber() > + << CurrentFnName; > else if (TM.getRelocationModel() == Reloc::PIC_) { > printBasicBlockLabel(MBB, false, false); > // If the arch uses custom Jump Table directives, don't calc > relative to JT > if (!TAI->getJumpTableDirective()) > O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" > - << getFunctionNumber() << '_' << JTI << '_' << > MO2.getImmedValue(); > + << JTI << '_' << MO2.getImmedValue() << '_' << > CurrentFnName; > } else > printBasicBlockLabel(MBB, false, false); > if (i != e-1) > > Modified: llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ > Alpha/AlphaAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp Fri Oct 12 > 09:53:36 2007 > @@ -104,8 +104,8 @@ > return; > > case MachineOperand::MO_ConstantPoolIndex: > - O << TAI->getPrivateGlobalPrefix() << "CPI" << > getFunctionNumber() << "_" > - << MO.getConstantPoolIndex(); > + O << TAI->getPrivateGlobalPrefix() << "CPI" << > MO.getConstantPoolIndex() > + << '_' << CurrentFnName; > return; > > case MachineOperand::MO_ExternalSymbol: > @@ -121,8 +121,8 @@ > } > > case MachineOperand::MO_JumpTableIndex: > - O << TAI->getPrivateGlobalPrefix() << "JTI" << > getFunctionNumber() > - << '_' << MO.getJumpTableIndex(); > + O << TAI->getPrivateGlobalPrefix() << "JTI" << > MO.getJumpTableIndex() > + << '_' << CurrentFnName; > return; > > default: > > Modified: llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/ > IA64AsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp Fri Oct 12 > 09:53:36 2007 > @@ -179,8 +179,8 @@ > return; > case MachineOperand::MO_ConstantPoolIndex: { > O << "@gprel(" << TAI->getPrivateGlobalPrefix() > - << "CPI" << getFunctionNumber() << "_" > - << MO.getConstantPoolIndex() << ")"; > + << "CPI" << MO.getConstantPoolIndex() << '_' > + << CurrentFnName << ")"; > return; > } > > > Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/ > MipsAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Fri Oct 12 > 09:53:36 2007 > @@ -363,7 +363,7 @@ > > case MachineOperand::MO_ConstantPoolIndex: > O << TAI->getPrivateGlobalPrefix() << "CPI" > - << getFunctionNumber() << "_" << MO.getConstantPoolIndex(); > + << MO.getConstantPoolIndex() << '_' << CurrentFnName; > break; > > default: > > Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ > PowerPC/PPCAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Fri Oct 12 > 09:53:36 2007 > @@ -164,7 +164,7 @@ > O << "lo16("; > printOp(MI->getOperand(OpNo)); > if (TM.getRelocationModel() == Reloc::PIC_) > - O << "-\"L" << getFunctionNumber() << "$pb\")"; > + O << "-\"L" "pb$" << CurrentFnName << "\")"; > else > O << ')'; > } > @@ -208,8 +208,8 @@ > O << (int)MI->getOperand(OpNo).getImmedValue()*4; > } > void printPICLabel(const MachineInstr *MI, unsigned OpNo) { > - O << "\"L" << getFunctionNumber() << "$pb\"\n"; > - O << "\"L" << getFunctionNumber() << "$pb\":"; > + O << "\"L" "pb$" << CurrentFnName << "\"\n"; > + O << "\"L" "pb$" << CurrentFnName << "\":"; > } > void printSymbolHi(const MachineInstr *MI, unsigned OpNo) { > if (MI->getOperand(OpNo).isImmediate()) { > @@ -218,7 +218,7 @@ > if (Subtarget.isDarwin()) O << "ha16("; > printOp(MI->getOperand(OpNo)); > if (TM.getRelocationModel() == Reloc::PIC_) > - O << "-\"L" << getFunctionNumber() << "$pb\""; > + O << "-\"L" "pb$" << CurrentFnName << "\""; > if (Subtarget.isDarwin()) > O << ')'; > else > @@ -232,7 +232,7 @@ > if (Subtarget.isDarwin()) O << "lo16("; > printOp(MI->getOperand(OpNo)); > if (TM.getRelocationModel() == Reloc::PIC_) > - O << "-\"L" << getFunctionNumber() << "$pb\""; > + O << "-\"L" "pb$" << CurrentFnName << "\""; > if (Subtarget.isDarwin()) > O << ')'; > else > @@ -362,13 +362,13 @@ > printBasicBlockLabel(MO.getMachineBasicBlock()); > return; > case MachineOperand::MO_JumpTableIndex: > - O << TAI->getPrivateGlobalPrefix() << "JTI" << > getFunctionNumber() > - << '_' << MO.getJumpTableIndex(); > + O << TAI->getPrivateGlobalPrefix() << "JTI" << > MO.getJumpTableIndex() > + << '_' << CurrentFnName; > // FIXME: PIC relocation model > return; > case MachineOperand::MO_ConstantPoolIndex: > - O << TAI->getPrivateGlobalPrefix() << "CPI" << > getFunctionNumber() > - << '_' << MO.getConstantPoolIndex(); > + O << TAI->getPrivateGlobalPrefix() << "CPI" << > MO.getConstantPoolIndex() > + << '_' << CurrentFnName; > return; > case MachineOperand::MO_ExternalSymbol: > // Computing the address of an external symbol, not calling it. > > Modified: llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ > Sparc/SparcAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp Fri Oct 12 > 09:53:36 2007 > @@ -164,8 +164,8 @@ > O << MO.getSymbolName(); > break; > case MachineOperand::MO_ConstantPoolIndex: > - O << TAI->getPrivateGlobalPrefix() << "CPI" << > getFunctionNumber() << "_" > - << MO.getConstantPoolIndex(); > + O << TAI->getPrivateGlobalPrefix() << "CPI" << > MO.getConstantPoolIndex() > + << '_' << CurrentFnName; > break; > default: > O << ""; abort (); break; > > Modified: llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/ > X86ATTAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp Fri Oct 12 > 09:53:36 2007 > @@ -31,14 +31,14 @@ > > STATISTIC(EmittedInsts, "Number of machine instrs printed"); > > -static std::string computePICLabel(unsigned FnNum, > +static std::string computePICLabel(const std::string &FnName, > const TargetAsmInfo *TAI, > const X86Subtarget* Subtarget) { > std::string label; > if (Subtarget->isTargetDarwin()) > - label = "\"L" + utostr_32(FnNum) + "$pb\""; > + label = "\"L" "pb$" + FnName + "\""; > else if (Subtarget->isTargetELF()) > - label = ".Lllvm$" + utostr_32(FnNum) + "$piclabel"; > + label = ".Lllvm$piclabel$" + FnName; > else > assert(0 && "Don't know how to print PIC label!\n"); > > @@ -236,13 +236,13 @@ > case MachineOperand::MO_JumpTableIndex: { > bool isMemOp = Modifier && !strcmp(Modifier, "mem"); > if (!isMemOp) O << '$'; > - O << TAI->getPrivateGlobalPrefix() << "JTI" << > getFunctionNumber() << "_" > - << MO.getJumpTableIndex(); > + O << TAI->getPrivateGlobalPrefix() << "JTI" << > MO.getJumpTableIndex() > + << '_' << CurrentFnName; > > if (TM.getRelocationModel() == Reloc::PIC_) { > if (Subtarget->isPICStyleStub()) > - O << "-\"" << TAI->getPrivateGlobalPrefix() << > getFunctionNumber() > - << "$pb\""; > + O << "-\"" << TAI->getPrivateGlobalPrefix() << "pb$" << > CurrentFnName > + << "\""; > else if (Subtarget->isPICStyleGOT()) > O << "@GOTOFF"; > } > @@ -254,13 +254,13 @@ > case MachineOperand::MO_ConstantPoolIndex: { > bool isMemOp = Modifier && !strcmp(Modifier, "mem"); > if (!isMemOp) O << '$'; > - O << TAI->getPrivateGlobalPrefix() << "CPI" << > getFunctionNumber() << "_" > - << MO.getConstantPoolIndex(); > + O << TAI->getPrivateGlobalPrefix() << "CPI" << > MO.getConstantPoolIndex() > + << '_' << CurrentFnName; > > if (TM.getRelocationModel() == Reloc::PIC_) { > if (Subtarget->isPICStyleStub()) > - O << "-\"" << TAI->getPrivateGlobalPrefix() << > getFunctionNumber() > - << "$pb\""; > + O << "-\"" << TAI->getPrivateGlobalPrefix() << "pb$" << > CurrentFnName > + << "\""; > else if (Subtarget->isPICStyleGOT()) > O << "@GOTOFF"; > } > @@ -317,8 +317,8 @@ > } > > if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_) > - O << "-\"" << TAI->getPrivateGlobalPrefix() << > getFunctionNumber() > - << "$pb\""; > + O << "-\"" << TAI->getPrivateGlobalPrefix() << "pb$" << > CurrentFnName > + << "\""; > } else { > if (GV->hasDLLImportLinkage()) { > O << "__imp_"; > @@ -418,7 +418,7 @@ > // popl %some_register > // addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], % > some_register > O << " + [.-" > - << computePICLabel(getFunctionNumber(), TAI, Subtarget) > << "]"; > + << computePICLabel(CurrentFnName, TAI, Subtarget) << "]"; > > if (isCallOp) > O << "@PLT"; > @@ -498,7 +498,7 @@ > } > > void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, > unsigned Op) { > - std::string label = computePICLabel(getFunctionNumber(), TAI, > Subtarget); > + std::string label = computePICLabel(CurrentFnName, TAI, Subtarget); > O << label << "\n" << label << ":"; > } > > > Modified: llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/ > X86IntelAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp Fri Oct 12 > 09:53:36 2007 > @@ -140,15 +140,15 @@ > case MachineOperand::MO_JumpTableIndex: { > bool isMemOp = Modifier && !strcmp(Modifier, "mem"); > if (!isMemOp) O << "OFFSET "; > - O << TAI->getPrivateGlobalPrefix() << "JTI" << > getFunctionNumber() > - << "_" << MO.getJumpTableIndex(); > + O << TAI->getPrivateGlobalPrefix() << "JTI" << > MO.getJumpTableIndex() > + << '_' << CurrentFnName; > return; > } > case MachineOperand::MO_ConstantPoolIndex: { > bool isMemOp = Modifier && !strcmp(Modifier, "mem"); > if (!isMemOp) O << "OFFSET "; > O << "[" << TAI->getPrivateGlobalPrefix() << "CPI" > - << getFunctionNumber() << "_" << MO.getConstantPoolIndex(); > + << MO.getConstantPoolIndex() << '_' << CurrentFnName; > int Offset = MO.getOffset(); > if (Offset > 0) > O << " + " << Offset; > @@ -236,8 +236,8 @@ > } > > void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, > unsigned Op) { > - O << "\"L" << getFunctionNumber() << "$pb\"\n"; > - O << "\"L" << getFunctionNumber() << "$pb\":"; > + O << "\"L" "pb$" << CurrentFnName << "\"\n"; > + O << "\"L" "pb$" << CurrentFnName << "\":"; > } > > bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand &MO, > > Modified: llvm/trunk/test/CodeGen/X86/2006-10-19- > SwitchUnnecessaryBranching.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ > X86/2006-10-19-SwitchUnnecessaryBranching.ll? > rev=42908&r1=42907&r2=42908&view=diff > > ====================================================================== > ======== > --- llvm/trunk/test/CodeGen/X86/2006-10-19- > SwitchUnnecessaryBranching.ll (original) > +++ llvm/trunk/test/CodeGen/X86/2006-10-19- > SwitchUnnecessaryBranching.ll Fri Oct 12 09:53:36 2007 > @@ -1,5 +1,5 @@ > ; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86 | %prcontext > je 1 | \ > -; RUN: grep BB1_1: > +; RUN: grep BB1_main: > > %str = internal constant [14 x sbyte] c"Hello world!\0A\00" ; < > [14 x sbyte]*> [#uses=1] > %str = internal constant [13 x sbyte] c"Blah world!\0A\00" ; <[13 > x sbyte]*> [#uses=1] > > Modified: llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ > X86/2007-01-08-InstrSched.ll?rev=42908&r1=42907&r2=42908&view=diff > > ====================================================================== > ======== > --- llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll (original) > +++ llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll Fri Oct 12 > 09:53:36 2007 > @@ -1,6 +1,6 @@ > ; PR1075 > ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | \ > -; RUN: %prcontext {mulss LCPI1_3} 1 | grep mulss | count 1 > +; RUN: %prcontext {mulss LCPI3__foo} 1 | grep mulss | count 1 > > define float @foo(float %x) { > %tmp1 = mul float %x, 3.000000e+00 > > Modified: llvm/trunk/test/CodeGen/X86/fp_constant_op.llx > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ > X86/fp_constant_op.llx?rev=42908&r1=42907&r2=42908&view=diff > > ====================================================================== > ======== > --- llvm/trunk/test/CodeGen/X86/fp_constant_op.llx (original) > +++ llvm/trunk/test/CodeGen/X86/fp_constant_op.llx Fri Oct 12 > 09:53:36 2007 > @@ -3,32 +3,32 @@ > > ; Test that the load of the constant is folded into the operation. > > -double %test_add(double %P) { > +double %foo_add(double %P) { > %tmp.1 = add double %P, 0x405EC00000000000 > ret double %tmp.1 > } > > -double %test_mul(double %P) { > +double %foo_mul(double %P) { > %tmp.1 = mul double %P, 0x405EC00000000000 > ret double %tmp.1 > } > > -double %test_sub(double %P) { > +double %foo_sub(double %P) { > %tmp.1 = sub double %P, 0x405EC00000000000 > ret double %tmp.1 > } > > -double %test_subr(double %P) { > +double %foo_subr(double %P) { > %tmp.1 = sub double 0x405EC00000000000, %P > ret double %tmp.1 > } > > -double %test_div(double %P) { > +double %foo_div(double %P) { > %tmp.1 = div double %P, 0x405EC00000000000 > ret double %tmp.1 > } > > -double %test_divr(double %P) { > +double %foo_divr(double %P) { > %tmp.1 = div double 0x405EC00000000000, %P > ret double %tmp.1 > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Sun Oct 14 00:51:19 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 13 Oct 2007 22:51:19 -0700 Subject: [llvm-commits] [llvm] r42908 - in /llvm/trunk: include/llvm/CodeGen/ lib/CodeGen/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/X86/ test/CodeGen/X86/ In-Reply-To: References: <200710121453.l9CEraSq016799@zion.cs.uiuc.edu> Message-ID: FYI. It's related to .set expression on x86-64. Defined as .set L0_set_302__yyparse,LBB302__yyparse-LJTI0__yyparse used as .long L0__set_302__yyparse Evan On Oct 13, 2007, at 10:48 PM, Evan Cheng wrote: > Hi Dan, > > I have to back out this patch for now. It's causing a lot of > x86-64 / Darwin (also possibly ARM / Darwin) compilation errors. > Please investigate. Thanks! > > Evan > > On Oct 12, 2007, at 7:53 AM, Dan Gohman wrote: > >> Author: djg >> Date: Fri Oct 12 09:53:36 2007 >> New Revision: 42908 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=42908&view=rev >> Log: >> Change the names used for internal labels to use the current >> function symbol name instead of a codegen-assigned function >> number. >> >> Thanks Evan! :-) >> >> Modified: >> llvm/trunk/include/llvm/CodeGen/AsmPrinter.h >> llvm/trunk/lib/CodeGen/AsmPrinter.cpp >> llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp >> llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp >> llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp >> llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp >> llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp >> llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp >> llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp >> llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp >> llvm/trunk/test/CodeGen/X86/2006-10-19- >> SwitchUnnecessaryBranching.ll >> llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll >> llvm/trunk/test/CodeGen/X86/fp_constant_op.llx >> >> Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ >> CodeGen/AsmPrinter.h?rev=42908&r1=42907&r2=42908&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original) >> +++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Fri Oct 12 >> 09:53:36 2007 >> @@ -36,13 +36,6 @@ >> class AsmPrinter : public MachineFunctionPass { >> static char ID; >> >> - /// FunctionNumber - This provides a unique ID for each >> function emitted in >> - /// this translation unit. It is autoincremented by >> SetupMachineFunction, >> - /// and can be accessed with getFunctionNumber() and >> - /// IncrementFunctionNumber(). >> - /// >> - unsigned FunctionNumber; >> - >> protected: >> // Necessary for external weak linkage support >> std::set ExtWeakSymbols; >> @@ -160,15 +153,6 @@ >> /// is being processed from runOnMachineFunction. >> void SetupMachineFunction(MachineFunction &MF); >> >> - /// getFunctionNumber - Return a unique ID for the current >> function. >> - /// >> - unsigned getFunctionNumber() const { return FunctionNumber; } >> - >> - /// IncrementFunctionNumber - Increase Function Number. >> AsmPrinters should >> - /// not normally call this, as the counter is automatically >> bumped by >> - /// SetupMachineFunction. >> - void IncrementFunctionNumber() { FunctionNumber++; } >> - >> /// EmitConstantPool - Print to the current output stream >> assembly >> /// representations of the constants in the constant pool MCP. >> This is >> /// used to print out constants which have been "spilled to >> memory" by >> >> Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ >> AsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original) >> +++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Fri Oct 12 09:53:36 2007 >> @@ -35,7 +35,7 @@ >> char AsmPrinter::ID = 0; >> AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm, >> const TargetAsmInfo *T) >> - : MachineFunctionPass((intptr_t)&ID), FunctionNumber(0), O(o), TM >> (tm), TAI(T) >> + : MachineFunctionPass((intptr_t)&ID), O(o), TM(tm), TAI(T) >> {} >> >> std::string AsmPrinter::getSectionForFunction(const Function &F) >> const { >> @@ -169,7 +169,6 @@ >> void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { >> // What's my mangled name? >> CurrentFnName = Mang->getValueName(MF.getFunction()); >> - IncrementFunctionNumber(); >> } >> >> /// EmitConstantPool - Print to the current output stream assembly >> @@ -219,8 +218,9 @@ >> SwitchToDataSection(Section); >> EmitAlignment(Alignment); >> for (unsigned i = 0, e = CP.size(); i != e; ++i) { >> - O << TAI->getPrivateGlobalPrefix() << "CPI" << >> getFunctionNumber() << '_' >> - << CP[i].second << ":\t\t\t\t\t" << TAI->getCommentString() >> << " "; >> + O << TAI->getPrivateGlobalPrefix() << "CPI" << CP[i].second >> + << '_' << CurrentFnName >> + << ":\t\t\t\t\t" << TAI->getCommentString() << ' '; >> WriteTypeSymbolic(O, CP[i].first.getType(), 0) << '\n'; >> if (CP[i].first.isMachineConstantPoolEntry()) >> EmitMachineConstantPoolValue(CP[i].first.Val.MachineCPVal); >> @@ -293,10 +293,10 @@ >> // the assembler and linker the extents of the jump table >> object. The >> // second label is actually referenced by the code. >> if (const char *JTLabelPrefix = TAI- >>> getJumpTableSpecialLabelPrefix()) >> - O << JTLabelPrefix << "JTI" << getFunctionNumber() << '_' << >> i << ":\n"; >> + O << JTLabelPrefix << "JTI" << i << '_' << CurrentFnName << >> ":\n"; >> >> - O << TAI->getPrivateGlobalPrefix() << "JTI" << >> getFunctionNumber() >> - << '_' << i << ":\n"; >> + O << TAI->getPrivateGlobalPrefix() << "JTI" << i >> + << '_' << CurrentFnName << ":\n"; >> >> for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { >> O << JTEntryDirective << ' '; >> @@ -306,15 +306,15 @@ >> // If we're emitting non-PIC code, then emit the entries as >> direct >> // references to the target basic blocks. >> if (!EmittedSets.empty()) { >> - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() >> - << '_' << i << "_set_" << JTBBs[ii]->getNumber(); >> + O << TAI->getPrivateGlobalPrefix() << i >> + << '_' << "_set_" << JTBBs[ii]->getNumber() << '_' << >> CurrentFnName; >> } else if (IsPic) { >> printBasicBlockLabel(JTBBs[ii], false, false); >> // If the arch uses custom Jump Table directives, don't >> calc relative to >> // JT >> if (!HadJTEntryDirective) >> O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" >> - << getFunctionNumber() << '_' << i; >> + << i << '_' << CurrentFnName; >> } else { >> printBasicBlockLabel(JTBBs[ii], false, false); >> } >> @@ -1242,8 +1242,8 @@ >> void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB, >> bool printColon, >> bool printComment) const { >> - O << TAI->getPrivateGlobalPrefix() << "BB" << getFunctionNumber >> () << "_" >> - << MBB->getNumber(); >> + O << TAI->getPrivateGlobalPrefix() << "BB" << MBB->getNumber() >> << '_' >> + << CurrentFnName; >> if (printColon) >> O << ':'; >> if (printComment && MBB->getBasicBlock()) >> @@ -1259,10 +1259,10 @@ >> return; >> >> O << TAI->getSetDirective() << ' ' << TAI- >> >getPrivateGlobalPrefix() >> - << getFunctionNumber() << '_' << uid << "_set_" << MBB- >>> getNumber() << ','; >> + << uid << "_set_" << MBB->getNumber() << '_' << CurrentFnName >> << ','; >> printBasicBlockLabel(MBB, false, false); >> - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << >> getFunctionNumber() >> - << '_' << uid << '\n'; >> + O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << uid >> + << '_' << CurrentFnName << '\n'; >> } >> >> void AsmPrinter::printSetLabel(unsigned uid, unsigned uid2, >> @@ -1271,11 +1271,11 @@ >> return; >> >> O << TAI->getSetDirective() << ' ' << TAI- >> >getPrivateGlobalPrefix() >> - << getFunctionNumber() << '_' << uid << '_' << uid2 >> - << "_set_" << MBB->getNumber() << ','; >> + << uid << '_' << uid2 >> + << "_set_" << MBB->getNumber() << '_' << CurrentFnName << ','; >> printBasicBlockLabel(MBB, false, false); >> - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << >> getFunctionNumber() >> - << '_' << uid << '_' << uid2 << '\n'; >> + O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << uid >> + << '_' << uid2 << '_' << CurrentFnName << '\n'; >> } >> >> /// printDataDirective - This method prints the asm directive for >> the >> >> Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ >> ARMAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original) >> +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Fri Oct 12 09:53:36 >> 2007 >> @@ -319,12 +319,12 @@ >> break; >> } >> case MachineOperand::MO_ConstantPoolIndex: >> - O << TAI->getPrivateGlobalPrefix() << "CPI" << >> getFunctionNumber() >> - << '_' << MO.getConstantPoolIndex(); >> + O << TAI->getPrivateGlobalPrefix() << "CPI" << >> MO.getConstantPoolIndex() >> + << '_' << CurrentFnName; >> break; >> case MachineOperand::MO_JumpTableIndex: >> - O << TAI->getPrivateGlobalPrefix() << "JTI" << >> getFunctionNumber() >> - << '_' << MO.getJumpTableIndex(); >> + O << TAI->getPrivateGlobalPrefix() << "JTI" << >> MO.getJumpTableIndex() >> + << '_' << CurrentFnName; >> break; >> default: >> O << ""; abort (); break; >> @@ -652,8 +652,8 @@ >> // data itself. >> if (!strcmp(Modifier, "label")) { >> unsigned ID = MI->getOperand(OpNo).getImm(); >> - O << TAI->getPrivateGlobalPrefix() << "CPI" << >> getFunctionNumber() >> - << '_' << ID << ":\n"; >> + O << TAI->getPrivateGlobalPrefix() << "CPI" << ID >> + << '_' << CurrentFnName << ":\n"; >> } else { >> assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for >> CPE"); >> unsigned CPI = MI->getOperand(OpNo).getConstantPoolIndex(); >> @@ -677,8 +677,8 @@ >> const MachineOperand &MO1 = MI->getOperand(OpNo); >> const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id >> unsigned JTI = MO1.getJumpTableIndex(); >> - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() >> - << '_' << JTI << '_' << MO2.getImmedValue() << ":\n"; >> + O << TAI->getPrivateGlobalPrefix() << "JTI" << JTI >> + << '_' << MO2.getImmedValue() << '_' << CurrentFnName << ":\n"; >> >> const char *JTEntryDirective = TAI->getJumpTableDirective(); >> if (!JTEntryDirective) >> @@ -697,15 +697,16 @@ >> >> O << JTEntryDirective << ' '; >> if (UseSet) >> - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() >> - << '_' << JTI << '_' << MO2.getImmedValue() >> - << "_set_" << MBB->getNumber(); >> + O << TAI->getPrivateGlobalPrefix() << JTI >> + << '_' << MO2.getImmedValue() >> + << "_set_" << MBB->getNumber() >> + << CurrentFnName; >> else if (TM.getRelocationModel() == Reloc::PIC_) { >> printBasicBlockLabel(MBB, false, false); >> // If the arch uses custom Jump Table directives, don't calc >> relative to JT >> if (!TAI->getJumpTableDirective()) >> O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" >> - << getFunctionNumber() << '_' << JTI << '_' << >> MO2.getImmedValue(); >> + << JTI << '_' << MO2.getImmedValue() << '_' << >> CurrentFnName; >> } else >> printBasicBlockLabel(MBB, false, false); >> if (i != e-1) >> >> Modified: llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ >> Alpha/AlphaAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp (original) >> +++ llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp Fri Oct 12 >> 09:53:36 2007 >> @@ -104,8 +104,8 @@ >> return; >> >> case MachineOperand::MO_ConstantPoolIndex: >> - O << TAI->getPrivateGlobalPrefix() << "CPI" << >> getFunctionNumber() << "_" >> - << MO.getConstantPoolIndex(); >> + O << TAI->getPrivateGlobalPrefix() << "CPI" << >> MO.getConstantPoolIndex() >> + << '_' << CurrentFnName; >> return; >> >> case MachineOperand::MO_ExternalSymbol: >> @@ -121,8 +121,8 @@ >> } >> >> case MachineOperand::MO_JumpTableIndex: >> - O << TAI->getPrivateGlobalPrefix() << "JTI" << >> getFunctionNumber() >> - << '_' << MO.getJumpTableIndex(); >> + O << TAI->getPrivateGlobalPrefix() << "JTI" << >> MO.getJumpTableIndex() >> + << '_' << CurrentFnName; >> return; >> >> default: >> >> Modified: llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/ >> IA64AsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp (original) >> +++ llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp Fri Oct 12 >> 09:53:36 2007 >> @@ -179,8 +179,8 @@ >> return; >> case MachineOperand::MO_ConstantPoolIndex: { >> O << "@gprel(" << TAI->getPrivateGlobalPrefix() >> - << "CPI" << getFunctionNumber() << "_" >> - << MO.getConstantPoolIndex() << ")"; >> + << "CPI" << MO.getConstantPoolIndex() << '_' >> + << CurrentFnName << ")"; >> return; >> } >> >> >> Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/ >> MipsAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original) >> +++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Fri Oct 12 >> 09:53:36 2007 >> @@ -363,7 +363,7 @@ >> >> case MachineOperand::MO_ConstantPoolIndex: >> O << TAI->getPrivateGlobalPrefix() << "CPI" >> - << getFunctionNumber() << "_" << MO.getConstantPoolIndex(); >> + << MO.getConstantPoolIndex() << '_' << CurrentFnName; >> break; >> >> default: >> >> Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ >> PowerPC/PPCAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original) >> +++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Fri Oct 12 >> 09:53:36 2007 >> @@ -164,7 +164,7 @@ >> O << "lo16("; >> printOp(MI->getOperand(OpNo)); >> if (TM.getRelocationModel() == Reloc::PIC_) >> - O << "-\"L" << getFunctionNumber() << "$pb\")"; >> + O << "-\"L" "pb$" << CurrentFnName << "\")"; >> else >> O << ')'; >> } >> @@ -208,8 +208,8 @@ >> O << (int)MI->getOperand(OpNo).getImmedValue()*4; >> } >> void printPICLabel(const MachineInstr *MI, unsigned OpNo) { >> - O << "\"L" << getFunctionNumber() << "$pb\"\n"; >> - O << "\"L" << getFunctionNumber() << "$pb\":"; >> + O << "\"L" "pb$" << CurrentFnName << "\"\n"; >> + O << "\"L" "pb$" << CurrentFnName << "\":"; >> } >> void printSymbolHi(const MachineInstr *MI, unsigned OpNo) { >> if (MI->getOperand(OpNo).isImmediate()) { >> @@ -218,7 +218,7 @@ >> if (Subtarget.isDarwin()) O << "ha16("; >> printOp(MI->getOperand(OpNo)); >> if (TM.getRelocationModel() == Reloc::PIC_) >> - O << "-\"L" << getFunctionNumber() << "$pb\""; >> + O << "-\"L" "pb$" << CurrentFnName << "\""; >> if (Subtarget.isDarwin()) >> O << ')'; >> else >> @@ -232,7 +232,7 @@ >> if (Subtarget.isDarwin()) O << "lo16("; >> printOp(MI->getOperand(OpNo)); >> if (TM.getRelocationModel() == Reloc::PIC_) >> - O << "-\"L" << getFunctionNumber() << "$pb\""; >> + O << "-\"L" "pb$" << CurrentFnName << "\""; >> if (Subtarget.isDarwin()) >> O << ')'; >> else >> @@ -362,13 +362,13 @@ >> printBasicBlockLabel(MO.getMachineBasicBlock()); >> return; >> case MachineOperand::MO_JumpTableIndex: >> - O << TAI->getPrivateGlobalPrefix() << "JTI" << >> getFunctionNumber() >> - << '_' << MO.getJumpTableIndex(); >> + O << TAI->getPrivateGlobalPrefix() << "JTI" << >> MO.getJumpTableIndex() >> + << '_' << CurrentFnName; >> // FIXME: PIC relocation model >> return; >> case MachineOperand::MO_ConstantPoolIndex: >> - O << TAI->getPrivateGlobalPrefix() << "CPI" << >> getFunctionNumber() >> - << '_' << MO.getConstantPoolIndex(); >> + O << TAI->getPrivateGlobalPrefix() << "CPI" << >> MO.getConstantPoolIndex() >> + << '_' << CurrentFnName; >> return; >> case MachineOperand::MO_ExternalSymbol: >> // Computing the address of an external symbol, not calling it. >> >> Modified: llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ >> Sparc/SparcAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp (original) >> +++ llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp Fri Oct 12 >> 09:53:36 2007 >> @@ -164,8 +164,8 @@ >> O << MO.getSymbolName(); >> break; >> case MachineOperand::MO_ConstantPoolIndex: >> - O << TAI->getPrivateGlobalPrefix() << "CPI" << >> getFunctionNumber() << "_" >> - << MO.getConstantPoolIndex(); >> + O << TAI->getPrivateGlobalPrefix() << "CPI" << >> MO.getConstantPoolIndex() >> + << '_' << CurrentFnName; >> break; >> default: >> O << ""; abort (); break; >> >> Modified: llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/ >> X86ATTAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp (original) >> +++ llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp Fri Oct 12 >> 09:53:36 2007 >> @@ -31,14 +31,14 @@ >> >> STATISTIC(EmittedInsts, "Number of machine instrs printed"); >> >> -static std::string computePICLabel(unsigned FnNum, >> +static std::string computePICLabel(const std::string &FnName, >> const TargetAsmInfo *TAI, >> const X86Subtarget* Subtarget) { >> std::string label; >> if (Subtarget->isTargetDarwin()) >> - label = "\"L" + utostr_32(FnNum) + "$pb\""; >> + label = "\"L" "pb$" + FnName + "\""; >> else if (Subtarget->isTargetELF()) >> - label = ".Lllvm$" + utostr_32(FnNum) + "$piclabel"; >> + label = ".Lllvm$piclabel$" + FnName; >> else >> assert(0 && "Don't know how to print PIC label!\n"); >> >> @@ -236,13 +236,13 @@ >> case MachineOperand::MO_JumpTableIndex: { >> bool isMemOp = Modifier && !strcmp(Modifier, "mem"); >> if (!isMemOp) O << '$'; >> - O << TAI->getPrivateGlobalPrefix() << "JTI" << >> getFunctionNumber() << "_" >> - << MO.getJumpTableIndex(); >> + O << TAI->getPrivateGlobalPrefix() << "JTI" << >> MO.getJumpTableIndex() >> + << '_' << CurrentFnName; >> >> if (TM.getRelocationModel() == Reloc::PIC_) { >> if (Subtarget->isPICStyleStub()) >> - O << "-\"" << TAI->getPrivateGlobalPrefix() << >> getFunctionNumber() >> - << "$pb\""; >> + O << "-\"" << TAI->getPrivateGlobalPrefix() << "pb$" << >> CurrentFnName >> + << "\""; >> else if (Subtarget->isPICStyleGOT()) >> O << "@GOTOFF"; >> } >> @@ -254,13 +254,13 @@ >> case MachineOperand::MO_ConstantPoolIndex: { >> bool isMemOp = Modifier && !strcmp(Modifier, "mem"); >> if (!isMemOp) O << '$'; >> - O << TAI->getPrivateGlobalPrefix() << "CPI" << >> getFunctionNumber() << "_" >> - << MO.getConstantPoolIndex(); >> + O << TAI->getPrivateGlobalPrefix() << "CPI" << >> MO.getConstantPoolIndex() >> + << '_' << CurrentFnName; >> >> if (TM.getRelocationModel() == Reloc::PIC_) { >> if (Subtarget->isPICStyleStub()) >> - O << "-\"" << TAI->getPrivateGlobalPrefix() << >> getFunctionNumber() >> - << "$pb\""; >> + O << "-\"" << TAI->getPrivateGlobalPrefix() << "pb$" << >> CurrentFnName >> + << "\""; >> else if (Subtarget->isPICStyleGOT()) >> O << "@GOTOFF"; >> } >> @@ -317,8 +317,8 @@ >> } >> >> if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_) >> - O << "-\"" << TAI->getPrivateGlobalPrefix() << >> getFunctionNumber() >> - << "$pb\""; >> + O << "-\"" << TAI->getPrivateGlobalPrefix() << "pb$" << >> CurrentFnName >> + << "\""; >> } else { >> if (GV->hasDLLImportLinkage()) { >> O << "__imp_"; >> @@ -418,7 +418,7 @@ >> // popl %some_register >> // addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], % >> some_register >> O << " + [.-" >> - << computePICLabel(getFunctionNumber(), TAI, Subtarget) >> << "]"; >> + << computePICLabel(CurrentFnName, TAI, Subtarget) << "]"; >> >> if (isCallOp) >> O << "@PLT"; >> @@ -498,7 +498,7 @@ >> } >> >> void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, >> unsigned Op) { >> - std::string label = computePICLabel(getFunctionNumber(), TAI, >> Subtarget); >> + std::string label = computePICLabel(CurrentFnName, TAI, >> Subtarget); >> O << label << "\n" << label << ":"; >> } >> >> >> Modified: llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/ >> X86IntelAsmPrinter.cpp?rev=42908&r1=42907&r2=42908&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp (original) >> +++ llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp Fri Oct 12 >> 09:53:36 2007 >> @@ -140,15 +140,15 @@ >> case MachineOperand::MO_JumpTableIndex: { >> bool isMemOp = Modifier && !strcmp(Modifier, "mem"); >> if (!isMemOp) O << "OFFSET "; >> - O << TAI->getPrivateGlobalPrefix() << "JTI" << >> getFunctionNumber() >> - << "_" << MO.getJumpTableIndex(); >> + O << TAI->getPrivateGlobalPrefix() << "JTI" << >> MO.getJumpTableIndex() >> + << '_' << CurrentFnName; >> return; >> } >> case MachineOperand::MO_ConstantPoolIndex: { >> bool isMemOp = Modifier && !strcmp(Modifier, "mem"); >> if (!isMemOp) O << "OFFSET "; >> O << "[" << TAI->getPrivateGlobalPrefix() << "CPI" >> - << getFunctionNumber() << "_" << MO.getConstantPoolIndex(); >> + << MO.getConstantPoolIndex() << '_' << CurrentFnName; >> int Offset = MO.getOffset(); >> if (Offset > 0) >> O << " + " << Offset; >> @@ -236,8 +236,8 @@ >> } >> >> void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, >> unsigned Op) { >> - O << "\"L" << getFunctionNumber() << "$pb\"\n"; >> - O << "\"L" << getFunctionNumber() << "$pb\":"; >> + O << "\"L" "pb$" << CurrentFnName << "\"\n"; >> + O << "\"L" "pb$" << CurrentFnName << "\":"; >> } >> >> bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand &MO, >> >> Modified: llvm/trunk/test/CodeGen/X86/2006-10-19- >> SwitchUnnecessaryBranching.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ >> X86/2006-10-19-SwitchUnnecessaryBranching.ll? >> rev=42908&r1=42907&r2=42908&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/test/CodeGen/X86/2006-10-19- >> SwitchUnnecessaryBranching.ll (original) >> +++ llvm/trunk/test/CodeGen/X86/2006-10-19- >> SwitchUnnecessaryBranching.ll Fri Oct 12 09:53:36 2007 >> @@ -1,5 +1,5 @@ >> ; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86 | %prcontext >> je 1 | \ >> -; RUN: grep BB1_1: >> +; RUN: grep BB1_main: >> >> %str = internal constant [14 x sbyte] c"Hello world!\0A\00" ; < >> [14 x sbyte]*> [#uses=1] >> %str = internal constant [13 x sbyte] c"Blah world!\0A\00" ; <[13 >> x sbyte]*> [#uses=1] >> >> Modified: llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ >> X86/2007-01-08-InstrSched.ll?rev=42908&r1=42907&r2=42908&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll (original) >> +++ llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll Fri Oct 12 >> 09:53:36 2007 >> @@ -1,6 +1,6 @@ >> ; PR1075 >> ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | \ >> -; RUN: %prcontext {mulss LCPI1_3} 1 | grep mulss | count 1 >> +; RUN: %prcontext {mulss LCPI3__foo} 1 | grep mulss | count 1 >> >> define float @foo(float %x) { >> %tmp1 = mul float %x, 3.000000e+00 >> >> Modified: llvm/trunk/test/CodeGen/X86/fp_constant_op.llx >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ >> X86/fp_constant_op.llx?rev=42908&r1=42907&r2=42908&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/test/CodeGen/X86/fp_constant_op.llx (original) >> +++ llvm/trunk/test/CodeGen/X86/fp_constant_op.llx Fri Oct 12 >> 09:53:36 2007 >> @@ -3,32 +3,32 @@ >> >> ; Test that the load of the constant is folded into the operation. >> >> -double %test_add(double %P) { >> +double %foo_add(double %P) { >> %tmp.1 = add double %P, 0x405EC00000000000 >> ret double %tmp.1 >> } >> >> -double %test_mul(double %P) { >> +double %foo_mul(double %P) { >> %tmp.1 = mul double %P, 0x405EC00000000000 >> ret double %tmp.1 >> } >> >> -double %test_sub(double %P) { >> +double %foo_sub(double %P) { >> %tmp.1 = sub double %P, 0x405EC00000000000 >> ret double %tmp.1 >> } >> >> -double %test_subr(double %P) { >> +double %foo_subr