From criswell at cs.uiuc.edu Mon Sep 24 08:37:44 2007 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 24 Sep 2007 10:37:44 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2007-SOSP-SVA.html Message-ID: <200709241537.KAA00305@choi.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2007-SOSP-SVA.html added (r1.1) --- Log message: Adding SOSP 2007 paper on Secure Virtual Architecture. --- Diffs of the changes: (+83 -0) 2007-SOSP-SVA.html | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 83 insertions(+) Index: llvm-www/pubs/2007-SOSP-SVA.html diff -c /dev/null llvm-www/pubs/2007-SOSP-SVA.html:1.1 *** /dev/null Mon Sep 24 10:37:04 2007 --- llvm-www/pubs/2007-SOSP-SVA.html Mon Sep 24 10:36:54 2007 *************** *** 0 **** --- 1,83 ---- + + + + + + Secure Virtual Architecture: A Safe Execution Environment for + Commodity Operating Systems + + + +
+ Secure Virtual Architecture: A Safe Execution Environment for + Commodity Operating Systems +
+
+ John Criswell, + Andrew Lenharth, + Dinakar Dhurjati, and + Vikram Adve +
+ +

Abstract:

+
+ This paper describes an efficient and robust + approach to provide a safe execution environment for an entire + operating system, such as Linux, and all its applications. The + approach, which we call Secure Virtual Architecture (SVA), + defines a virtual, low-level, typed instruction set suitable for + executing all code on a system, including kernel and + application code. SVA code is translated for execution by a virtual + machine transparently, offline or online. + SVA aims to enforce fine-grained (object level) memory safety, + control-flow integrity, + type safety for a subset of objects, and sound analysis. + A virtual machine implementing SVA achieves these goals by using a + novel approach that exploits properties of existing memory pools in + the kernel and by preserving the kernel's explicit control over + memory, including custom allocators and explicit deallocation. + Furthermore, the safety properties can be encoded compactly as + extensions to the SVA type system, + allowing the (complex) safety checking compiler to be outside + the trusted computing base. SVA also defines a set of OS interface + operations that abstract all privileged hardware instructions, + allowing the virtual machine to monitor all privileged operations + and control the physical resources on a given hardware platform. + We have ported the Linux kernel to SVA, treating it as a new + architecture, and made only minimal code changes (less than 300 lines of code) + to the machine-independent parts of the kernel and device drivers. + SVA is able to prevent 4 out of 5 memory safety exploits previously reported + for the Linux 2.4.22 kernel for which exploit code is available, and would + prevent the fifth one simply by compiling an additional kernel library. +
+ +

Download:

+

Paper:

+ + +

BibTeX Entry:

+
+ @inproceedings{SVA:SOSP07,
+  author = {John Criswell, Andrew Lenharth , Dinakar Dhurjati, and Vikram Adve},
+  title = {Secure Virtual Architecture: A Safe Execution Environment for Commodity Operating Systems},
+  booktitle = {SOSP '07: Proceedings of the Twenty First ACM Symposium on Operating Systems Principles},
+  month = {October},
+  year = {2007},
+  location = {Stevenson, WA},
+ }
+ 
+ + +
+ Valid CSS! + Valid HTML 4.01! + + + From criswell at cs.uiuc.edu Mon Sep 24 08:43:56 2007 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 24 Sep 2007 10:43:56 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2007-10-17-SOSP-SVA.html Message-ID: <200709241543.KAA00378@choi.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2007-10-17-SOSP-SVA.html added (r1.1) --- Log message: --- Diffs of the changes: (+83 -0) 2007-10-17-SOSP-SVA.html | 83 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 83 insertions(+) Index: llvm-www/pubs/2007-10-17-SOSP-SVA.html diff -c /dev/null llvm-www/pubs/2007-10-17-SOSP-SVA.html:1.1 *** /dev/null Mon Sep 24 10:43:40 2007 --- llvm-www/pubs/2007-10-17-SOSP-SVA.html Mon Sep 24 10:43:30 2007 *************** *** 0 **** --- 1,83 ---- + + + + + + Secure Virtual Architecture: A Safe Execution Environment for + Commodity Operating Systems + + + +
+ Secure Virtual Architecture: A Safe Execution Environment for + Commodity Operating Systems +
+
+ John Criswell, + Andrew Lenharth, + Dinakar Dhurjati, and + Vikram Adve +
+ +

Abstract:

+
+ This paper describes an efficient and robust + approach to provide a safe execution environment for an entire + operating system, such as Linux, and all its applications. The + approach, which we call Secure Virtual Architecture (SVA), + defines a virtual, low-level, typed instruction set suitable for + executing all code on a system, including kernel and + application code. SVA code is translated for execution by a virtual + machine transparently, offline or online. + SVA aims to enforce fine-grained (object level) memory safety, + control-flow integrity, + type safety for a subset of objects, and sound analysis. + A virtual machine implementing SVA achieves these goals by using a + novel approach that exploits properties of existing memory pools in + the kernel and by preserving the kernel's explicit control over + memory, including custom allocators and explicit deallocation. + Furthermore, the safety properties can be encoded compactly as + extensions to the SVA type system, + allowing the (complex) safety checking compiler to be outside + the trusted computing base. SVA also defines a set of OS interface + operations that abstract all privileged hardware instructions, + allowing the virtual machine to monitor all privileged operations + and control the physical resources on a given hardware platform. + We have ported the Linux kernel to SVA, treating it as a new + architecture, and made only minimal code changes (less than 300 lines of code) + to the machine-independent parts of the kernel and device drivers. + SVA is able to prevent 4 out of 5 memory safety exploits previously reported + for the Linux 2.4.22 kernel for which exploit code is available, and would + prevent the fifth one simply by compiling an additional kernel library. +
+ +

Download:

+

Paper:

+ + +

BibTeX Entry:

+
+ @inproceedings{SVA:SOSP07,
+  author = {John Criswell, Andrew Lenharth , Dinakar Dhurjati, and Vikram Adve},
+  title = {Secure Virtual Architecture: A Safe Execution Environment for Commodity Operating Systems},
+  booktitle = {SOSP '07: Proceedings of the Twenty First ACM Symposium on Operating Systems Principles},
+  month = {October},
+  year = {2007},
+  location = {Stevenson, WA},
+ }
+ 
+ + +
+ Valid CSS! + Valid HTML 4.01! + + + From djg at cray.com Mon Sep 24 08:46:02 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 24 Sep 2007 15:46:02 -0000 Subject: [llvm-commits] [llvm] r42261 - /llvm/trunk/include/llvm/Instructions.h Message-ID: <200709241546.l8OFk3Jt023425@zion.cs.uiuc.edu> Author: djg Date: Mon Sep 24 10:46:02 2007 New Revision: 42261 URL: http://llvm.org/viewvc/llvm-project?rev=42261&view=rev Log: Remove an unnecessary static_cast. Modified: llvm/trunk/include/llvm/Instructions.h Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=42261&r1=42260&r2=42261&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Mon Sep 24 10:46:02 2007 @@ -917,7 +917,7 @@ /// if it is a direct call. If it is a call through a function pointer, /// return null. Function *getCalledFunction() const { - return static_cast(dyn_cast(getOperand(0))); + return dyn_cast(getOperand(0)); } /// getCalledValue - Get a pointer to the function that is invoked by this From djg at cray.com Mon Sep 24 08:48:49 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 24 Sep 2007 15:48:49 -0000 Subject: [llvm-commits] [llvm] r42262 - in /llvm/trunk: include/llvm/CodeGen/MachineModuleInfo.h lib/Transforms/Scalar/GVNPRE.cpp Message-ID: <200709241548.l8OFmnQn023490@zion.cs.uiuc.edu> Author: djg Date: Mon Sep 24 10:48:49 2007 New Revision: 42262 URL: http://llvm.org/viewvc/llvm-project?rev=42262&view=rev Log: explicit keywords. Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h llvm/trunk/lib/Transforms/Scalar/GVNPRE.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h?rev=42262&r1=42261&r2=42262&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Mon Sep 24 10:48:49 2007 @@ -161,7 +161,7 @@ public: AnchorDesc(); - AnchorDesc(AnchoredDesc *D); + explicit AnchorDesc(AnchoredDesc *D); // Accessors unsigned getAnchorTag() const { return AnchorTag; } @@ -201,7 +201,7 @@ protected: - AnchoredDesc(unsigned T); + explicit AnchoredDesc(unsigned T); public: // Accessors. @@ -291,7 +291,7 @@ unsigned Flags; // Miscellaneous flags. public: - TypeDesc(unsigned T); + explicit TypeDesc(unsigned T); // Accessors DebugInfoDesc *getContext() const { return Context; } @@ -382,7 +382,7 @@ DebugInfoDesc *FromType; // Type derived from. public: - DerivedTypeDesc(unsigned T); + explicit DerivedTypeDesc(unsigned T); // Accessors TypeDesc *getFromType() const { @@ -421,7 +421,7 @@ std::vector Elements;// Information used to compose type. public: - CompositeTypeDesc(unsigned T); + explicit CompositeTypeDesc(unsigned T); // Accessors std::vector &getElements() { return Elements; } @@ -536,7 +536,7 @@ DebugInfoDesc *TyDesc; // Type of variable. public: - VariableDesc(unsigned T); + explicit VariableDesc(unsigned T); // Accessors DebugInfoDesc *getContext() const { return Context; } @@ -595,7 +595,7 @@ bool IsDefinition; // Is the global defined in context. protected: - GlobalDesc(unsigned T); + explicit GlobalDesc(unsigned T); public: // Accessors @@ -962,7 +962,7 @@ Function *Personality; // Personality function. std::vector TypeIds; // List of type ids (filters negative) - LandingPadInfo(MachineBasicBlock *MBB) + explicit LandingPadInfo(MachineBasicBlock *MBB) : LandingPadBlock(MBB) , LandingPadLabel(0) , Personality(NULL) Modified: llvm/trunk/lib/Transforms/Scalar/GVNPRE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVNPRE.cpp?rev=42262&r1=42261&r2=42262&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVNPRE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVNPRE.cpp Mon Sep 24 10:48:49 2007 @@ -70,7 +70,7 @@ SmallVector varargs; Expression() { } - Expression(ExpressionOpcode o) : opcode(o) { } + explicit Expression(ExpressionOpcode o) : opcode(o) { } bool operator==(const Expression &other) const { if (opcode != other.opcode) From djg at cray.com Mon Sep 24 08:50:11 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 24 Sep 2007 15:50:11 -0000 Subject: [llvm-commits] [llvm] r42263 - /llvm/trunk/test/CodeGen/Generic/fwdtwice.ll Message-ID: <200709241550.l8OFoBvl023537@zion.cs.uiuc.edu> Author: djg Date: Mon Sep 24 10:50:11 2007 New Revision: 42263 URL: http://llvm.org/viewvc/llvm-project?rev=42263&view=rev Log: Fix a typo in a comment. Modified: llvm/trunk/test/CodeGen/Generic/fwdtwice.ll Modified: llvm/trunk/test/CodeGen/Generic/fwdtwice.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/fwdtwice.ll?rev=42263&r1=42262&r2=42263&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Generic/fwdtwice.ll (original) +++ llvm/trunk/test/CodeGen/Generic/fwdtwice.ll Mon Sep 24 10:50:11 2007 @@ -4,7 +4,7 @@ ;; Test the sequence: ;; cast -> setle 0, %cast -> br %cond ;; This sequence should cause the cast value to be forwarded twice, -;; i.e., cast is forwarded to the setle and teh setle is forwarded +;; i.e., cast is forwarded to the setle and the setle is forwarded ;; to the branch. ;; register argument of the "branch-on-register" instruction, i.e., ;; From criswell at cs.uiuc.edu Mon Sep 24 08:50:47 2007 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 24 Sep 2007 10:50:47 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/index.html Message-ID: <200709241550.KAA00434@choi.cs.uiuc.edu> Changes in directory llvm-www/pubs: index.html updated: 1.58 -> 1.59 --- Log message: Added SOSP paper on Secure Virtual Architecture. --- Diffs of the changes: (+7 -0) index.html | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm-www/pubs/index.html diff -u llvm-www/pubs/index.html:1.58 llvm-www/pubs/index.html:1.59 --- llvm-www/pubs/index.html:1.58 Tue Aug 28 00:17:12 2007 +++ llvm-www/pubs/index.html Mon Sep 24 10:50:20 2007 @@ -3,6 +3,13 @@
    +
  1. +Secure Virtual Architecture: A Safe Execution Environment for Commodity +Operating Systems
    John Criswell, Andrew Lenharth, Dinakar Dhurjati, and +Vikram Adve +
    +Proceedings of the Twenty First ACM Symposium on Operating Systems Principles (SOSP '07), Stevenson, WA, October 2007.
  2. +
  3. "Transactifying Applications Using an Open Compiler Framework"
    Pascal Felber, Christof Fetzer, Ulrich Mueller, Torvald Riegel, Martin Suesskraut, and Heiko Sturzrehm
    From djg at cray.com Mon Sep 24 08:54:54 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 24 Sep 2007 15:54:54 -0000 Subject: [llvm-commits] [llvm] r42264 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp test/CodeGen/X86/extractelement-from-arg.ll Message-ID: <200709241554.l8OFssFa023645@zion.cs.uiuc.edu> Author: djg Date: Mon Sep 24 10:54:53 2007 New Revision: 42264 URL: http://llvm.org/viewvc/llvm-project?rev=42264&view=rev Log: Use the correct result value type instead of using getValueType(0) in ExpandEXTRACT_VECTOR_ELT and SplitVectorOp. This fixes an abort in the included testcase. Added: llvm/trunk/test/CodeGen/X86/extractelement-from-arg.ll 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=42264&r1=42263&r2=42264&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Sep 24 10:54:53 2007 @@ -3870,8 +3870,7 @@ SDOperand Vec = Op.getOperand(0); SDOperand Idx = Op.getOperand(1); - SDNode *InVal = Vec.Val; - MVT::ValueType TVT = InVal->getValueType(0); + MVT::ValueType TVT = Vec.getValueType(); unsigned NumElems = MVT::getVectorNumElements(TVT); switch (TLI.getOperationAction(ISD::EXTRACT_VECTOR_ELT, TVT)) { @@ -5803,10 +5802,10 @@ SDOperand &Hi) { assert(MVT::isVector(Op.getValueType()) && "Cannot split non-vector type!"); SDNode *Node = Op.Val; - unsigned NumElements = MVT::getVectorNumElements(Node->getValueType(0)); + unsigned NumElements = MVT::getVectorNumElements(Op.getValueType()); assert(NumElements > 1 && "Cannot split a single element vector!"); unsigned NewNumElts = NumElements/2; - MVT::ValueType NewEltVT = MVT::getVectorElementType(Node->getValueType(0)); + MVT::ValueType NewEltVT = MVT::getVectorElementType(Op.getValueType()); MVT::ValueType NewVT = MVT::getVectorType(NewEltVT, NewNumElts); // See if we already split it. Added: llvm/trunk/test/CodeGen/X86/extractelement-from-arg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/extractelement-from-arg.ll?rev=42264&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/extractelement-from-arg.ll (added) +++ llvm/trunk/test/CodeGen/X86/extractelement-from-arg.ll Mon Sep 24 10:54:53 2007 @@ -0,0 +1,7 @@ +; RUN: llvm-as %s -o - | llc -march=x86-64 + +define void @test(float* %R, <4 x float> %X) { + %tmp = extractelement <4 x float> %X, i32 3 + store float %tmp, float* %R + ret void +} From lattner at apple.com Mon Sep 24 09:42:25 2007 From: lattner at apple.com (Tanya Lattner) Date: Mon, 24 Sep 2007 09:42:25 -0700 Subject: [llvm-commits] [llvm] r42248 - in /llvm/trunk: include/llvm/Analysis/Dominators.h include/llvm/Analysis/PostDominators.h lib/VMCore/DominatorCalculation.h lib/VMCore/Dominators.cpp In-Reply-To: <200709232131.l8NLVj7d021367@zion.cs.uiuc.edu> References: <200709232131.l8NLVj7d021367@zion.cs.uiuc.edu> Message-ID: <6D167084-13AC-4D81-8C89-0AD05558D9A5@apple.com> Owen, Could you please add doxygen style comments for the new functions you are adding/moving? Its useful to have comments before the function describing what it does. Thanks, Tanya On Sep 23, 2007, at 2:31 PM, Owen Anderson wrote: > Author: resistor > Date: Sun Sep 23 16:31:44 2007 > New Revision: 42248 > > URL: http://llvm.org/viewvc/llvm-project?rev=42248&view=rev > Log: > Factor the dominator tree calculation details out into > DominatorCalculation.h. This > change is not useful in and of itself, but it lays the groundwork > for combining > the dominator and postdominator implementations. > > Also, factor a few methods that are common to DominatorTree and > PostDominatorTree > into DominatorTreeBase. Again, this will make merging the two > calculation methods > simpler in the future. > > Added: > llvm/trunk/lib/VMCore/DominatorCalculation.h > Modified: > llvm/trunk/include/llvm/Analysis/Dominators.h > llvm/trunk/include/llvm/Analysis/PostDominators.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=42248&r1=42247&r2=42248&view=diff > > ====================================================================== > ======== > --- llvm/trunk/include/llvm/Analysis/Dominators.h (original) > +++ llvm/trunk/include/llvm/Analysis/Dominators.h Sun Sep 23 > 16:31:44 2007 > @@ -129,6 +129,7 @@ > > // Info - Collection of information used during the computation > of idoms. > DenseMap Info; > + unsigned DFSPass(BasicBlock *V, unsigned N); > > public: > DominatorTreeBase(intptr_t ID, bool isPostDom) > @@ -278,6 +279,13 @@ > /// updateDFSNumbers - Assign In and Out numbers to the nodes > while walking > /// dominator tree in dfs order. > void updateDFSNumbers(); > + > + DomTreeNode *getNodeForBlock(BasicBlock *BB); > + > + inline BasicBlock *getIDom(BasicBlock *BB) const { > + DenseMap::const_iterator I = > IDoms.find(BB); > + return I != IDoms.end() ? I->second : 0; > + } > }; > > //===------------------------------------- > @@ -304,17 +312,13 @@ > /// BB is split and now it has one successor. Update dominator > tree to > /// reflect this change. > void splitBlock(BasicBlock *BB); > + > private: > - void calculate(Function& F); > - DomTreeNode *getNodeForBlock(BasicBlock *BB); > - unsigned DFSPass(BasicBlock *V, unsigned N); > - void Compress(BasicBlock *V); > - BasicBlock *Eval(BasicBlock *v); > - void Link(BasicBlock *V, BasicBlock *W, InfoRec &WInfo); > - inline BasicBlock *getIDom(BasicBlock *BB) const { > - DenseMap::const_iterator I = > IDoms.find(BB); > - return I != IDoms.end() ? I->second : 0; > - } > + friend void DTcalculate(DominatorTree& DT, Function& F); > + friend void DTCompress(DominatorTree& DT, BasicBlock *VIn); > + friend BasicBlock *DTEval(DominatorTree& DT, BasicBlock *v); > + friend void DTLink(DominatorTree& DT, BasicBlock *V, > + BasicBlock *W, InfoRec &WInfo); > }; > > //===------------------------------------- > > Modified: llvm/trunk/include/llvm/Analysis/PostDominators.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ > Analysis/PostDominators.h?rev=42248&r1=42247&r2=42248&view=diff > > ====================================================================== > ======== > --- llvm/trunk/include/llvm/Analysis/PostDominators.h (original) > +++ llvm/trunk/include/llvm/Analysis/PostDominators.h Sun Sep 23 > 16:31:44 2007 > @@ -38,16 +38,10 @@ > } > private: > void calculate(Function &F); > - DomTreeNode *getNodeForBlock(BasicBlock *BB); > unsigned DFSPass(BasicBlock *V, unsigned N); > void Compress(BasicBlock *V, InfoRec &VInfo); > BasicBlock *Eval(BasicBlock *V); > void Link(BasicBlock *V, BasicBlock *W, InfoRec &WInfo); > - > - inline BasicBlock *getIDom(BasicBlock *BB) const { > - DenseMap::const_iterator I = > IDoms.find(BB); > - return I != IDoms.end() ? I->second : 0; > - } > }; > > > > Added: llvm/trunk/lib/VMCore/DominatorCalculation.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ > DominatorCalculation.h?rev=42248&view=auto > > ====================================================================== > ======== > --- llvm/trunk/lib/VMCore/DominatorCalculation.h (added) > +++ llvm/trunk/lib/VMCore/DominatorCalculation.h Sun Sep 23 > 16:31:44 2007 > @@ -0,0 +1,213 @@ > +//==- llvm/VMCore/DominatorCalculation.h - Dominator Calculation - > *- C++ -*-==// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file was developed by Owen Anderson and is distributed under > +// the University of Illinois Open Source License. See LICENSE.TXT > for details. > +// > +// > ===------------------------------------------------------------------- > ---===// > + > +#ifndef LLVM_VMCORE_DOMINATOR_CALCULATION_H > +#define LLVM_VMCORE_DOMINATOR_CALCULATION_H > + > +#include "llvm/Analysis/Dominators.h" > + > +// > ===------------------------------------------------------------------- > ---===// > +// > +// DominatorTree construction - This pass constructs immediate > dominator > +// information for a flow-graph based on the algorithm described > in this > +// document: > +// > +// A Fast Algorithm for Finding Dominators in a Flowgraph > +// T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141. > +// > +// This implements both the O(n*ack(n)) and the O(n*log(n)) > versions of EVAL and > +// LINK, but it turns out that the theoretically slower O(n*log(n)) > +// implementation is actually faster than the "efficient" > algorithm (even for > +// large CFGs) because the constant overheads are substantially > smaller. The > +// lower-complexity version can be enabled with the following > #define: > +// > +#define BALANCE_IDOM_TREE 0 > +// > +// > ===------------------------------------------------------------------- > ---===// > + > +namespace llvm { > + > +void DTCompress(DominatorTree& DT, BasicBlock *VIn) { > + > + std::vector Work; > + SmallPtrSet Visited; > + BasicBlock *VInAncestor = DT.Info[VIn].Ancestor; > + DominatorTree::InfoRec &VInVAInfo = DT.Info[VInAncestor]; > + > + if (VInVAInfo.Ancestor != 0) > + Work.push_back(VIn); > + > + while (!Work.empty()) { > + BasicBlock *V = Work.back(); > + DominatorTree::InfoRec &VInfo = DT.Info[V]; > + BasicBlock *VAncestor = VInfo.Ancestor; > + DominatorTree::InfoRec &VAInfo = DT.Info[VAncestor]; > + > + // Process Ancestor first > + if (Visited.insert(VAncestor) && > + VAInfo.Ancestor != 0) { > + Work.push_back(VAncestor); > + continue; > + } > + Work.pop_back(); > + > + // Update VInfo based on Ancestor info > + if (VAInfo.Ancestor == 0) > + continue; > + BasicBlock *VAncestorLabel = VAInfo.Label; > + BasicBlock *VLabel = VInfo.Label; > + if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi) > + VInfo.Label = VAncestorLabel; > + VInfo.Ancestor = VAInfo.Ancestor; > + } > +} > + > +BasicBlock *DTEval(DominatorTree& DT, BasicBlock *V) { > + DominatorTree::InfoRec &VInfo = DT.Info[V]; > +#if !BALANCE_IDOM_TREE > + // Higher-complexity but faster implementation > + if (VInfo.Ancestor == 0) > + return V; > + DTCompress(DT, V); > + return VInfo.Label; > +#else > + // Lower-complexity but slower implementation > + if (VInfo.Ancestor == 0) > + return VInfo.Label; > + DTCompress(DT, V); > + BasicBlock *VLabel = VInfo.Label; > + > + BasicBlock *VAncestorLabel = DT.Info[VInfo.Ancestor].Label; > + if (DT.Info[VAncestorLabel].Semi >= DT.Info[VLabel].Semi) > + return VLabel; > + else > + return VAncestorLabel; > +#endif > +} > + > +void DTLink(DominatorTree& DT, BasicBlock *V, BasicBlock *W, > + DominatorTree::InfoRec &WInfo) { > +#if !BALANCE_IDOM_TREE > + // Higher-complexity but faster implementation > + WInfo.Ancestor = V; > +#else > + // Lower-complexity but slower implementation > + BasicBlock *WLabel = WInfo.Label; > + unsigned WLabelSemi = Info[WLabel].Semi; > + BasicBlock *S = W; > + InfoRec *SInfo = &Info[S]; > + > + BasicBlock *SChild = SInfo->Child; > + InfoRec *SChildInfo = &Info[SChild]; > + > + while (WLabelSemi < Info[SChildInfo->Label].Semi) { > + BasicBlock *SChildChild = SChildInfo->Child; > + if (SInfo->Size+Info[SChildChild].Size >= 2*SChildInfo->Size) { > + SChildInfo->Ancestor = S; > + SInfo->Child = SChild = SChildChild; > + SChildInfo = &Info[SChild]; > + } else { > + SChildInfo->Size = SInfo->Size; > + S = SInfo->Ancestor = SChild; > + SInfo = SChildInfo; > + SChild = SChildChild; > + SChildInfo = &Info[SChild]; > + } > + } > + > + InfoRec &VInfo = Info[V]; > + SInfo->Label = WLabel; > + > + assert(V != W && "The optimization here will not work in this > case!"); > + unsigned WSize = WInfo.Size; > + unsigned VSize = (VInfo.Size += WSize); > + > + if (VSize < 2*WSize) > + std::swap(S, VInfo.Child); > + > + while (S) { > + SInfo = &Info[S]; > + SInfo->Ancestor = V; > + S = SInfo->Child; > + } > +#endif > +} > + > +void DTcalculate(DominatorTree& DT, Function &F) { > + BasicBlock* Root = DT.Roots[0]; > + > + // Add a node for the root... > + DT.DomTreeNodes[Root] = DT.RootNode = new DomTreeNode(Root, 0); > + > + DT.Vertex.push_back(0); > + > + // Step #1: Number blocks in depth-first order and initialize > variables used > + // in later stages of the algorithm. > + unsigned N = DT.DFSPass(Root, 0); > + > + for (unsigned i = N; i >= 2; --i) { > + BasicBlock *W = DT.Vertex[i]; > + DominatorTree::InfoRec &WInfo = DT.Info[W]; > + > + // Step #2: Calculate the semidominators of all vertices > + for (pred_iterator PI = pred_begin(W), E = pred_end(W); PI != > E; ++PI) > + if (DT.Info.count(*PI)) { // Only if this predecessor is > reachable! > + unsigned SemiU = DT.Info[DTEval(DT, *PI)].Semi; > + if (SemiU < WInfo.Semi) > + WInfo.Semi = SemiU; > + } > + > + DT.Info[DT.Vertex[WInfo.Semi]].Bucket.push_back(W); > + > + BasicBlock *WParent = WInfo.Parent; > + DTLink(DT, WParent, W, WInfo); > + > + // Step #3: Implicitly define the immediate dominator of vertices > + std::vector &WParentBucket = DT.Info > [WParent].Bucket; > + while (!WParentBucket.empty()) { > + BasicBlock *V = WParentBucket.back(); > + WParentBucket.pop_back(); > + BasicBlock *U = DTEval(DT, V); > + DT.IDoms[V] = DT.Info[U].Semi < DT.Info[V].Semi ? U : WParent; > + } > + } > + > + // Step #4: Explicitly define the immediate dominator of each > vertex > + for (unsigned i = 2; i <= N; ++i) { > + BasicBlock *W = DT.Vertex[i]; > + BasicBlock *&WIDom = DT.IDoms[W]; > + if (WIDom != DT.Vertex[DT.Info[W].Semi]) > + WIDom = DT.IDoms[WIDom]; > + } > + > + // Loop over all of the reachable blocks in the function... > + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) > + if (BasicBlock *ImmDom = DT.getIDom(I)) { // Reachable block. > + DomTreeNode *BBNode = DT.DomTreeNodes[I]; > + if (BBNode) continue; // Haven't calculated this node yet? > + > + // Get or calculate the node for the immediate dominator > + DomTreeNode *IDomNode = DT.getNodeForBlock(ImmDom); > + > + // Add a new tree node for this BasicBlock, and link it as a > child of > + // IDomNode > + DomTreeNode *C = new DomTreeNode(I, IDomNode); > + DT.DomTreeNodes[I] = IDomNode->addChild(C); > + } > + > + // Free temporary memory used to construct idom's > + DT.Info.clear(); > + DT.IDoms.clear(); > + std::vector().swap(DT.Vertex); > + > + DT.updateDFSNumbers(); > +} > + > +} > +#endif > \ No newline at end of file > > Modified: llvm/trunk/lib/VMCore/Dominators.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ > Dominators.cpp?rev=42248&r1=42247&r2=42248&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/VMCore/Dominators.cpp (original) > +++ llvm/trunk/lib/VMCore/Dominators.cpp Sun Sep 23 16:31:44 2007 > @@ -23,6 +23,7 @@ > #include "llvm/ADT/SmallVector.h" > #include "llvm/Instructions.h" > #include "llvm/Support/Streams.h" > +#include "DominatorCalculation.h" > #include > using namespace llvm; > > @@ -43,20 +44,8 @@ > // DominatorTree Implementation > // > ===------------------------------------------------------------------- > ---===// > // > -// DominatorTree construction - This pass constructs immediate > dominator > -// information for a flow-graph based on the algorithm described > in this > -// document: > -// > -// A Fast Algorithm for Finding Dominators in a Flowgraph > -// T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141. > -// > -// This implements both the O(n*ack(n)) and the O(n*log(n)) > versions of EVAL and > -// LINK, but it turns out that the theoretically slower O(n*log(n)) > -// implementation is actually faster than the "efficient" > algorithm (even for > -// large CFGs) because the constant overheads are substantially > smaller. The > -// lower-complexity version can be enabled with the following > #define: > -// > -#define BALANCE_IDOM_TREE 0 > +// Provide public access to DominatorTree information. > Implementation details > +// can be found in DominatorCalculation.h. > // > // > ===------------------------------------------------------------------- > ---===// > > @@ -64,6 +53,68 @@ > static RegisterPass > E("domtree", "Dominator Tree Construction", true); > > +unsigned DominatorTreeBase::DFSPass(BasicBlock *V, unsigned N) { > + // This is more understandable as a recursive algorithm, but we > can't use the > + // recursive algorithm due to stack depth issues. Keep it here for > + // documentation purposes. > +#if 0 > + InfoRec &VInfo = Info[Roots[i]]; > + VInfo.Semi = ++N; > + VInfo.Label = V; > + > + Vertex.push_back(V); // Vertex[n] = V; > + //Info[V].Ancestor = 0; // Ancestor[n] = 0 > + //Info[V].Child = 0; // Child[v] = 0 > + VInfo.Size = 1; // Size[v] = 1 > + > + for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E; > ++SI) { > + InfoRec &SuccVInfo = Info[*SI]; > + if (SuccVInfo.Semi == 0) { > + SuccVInfo.Parent = V; > + N = DFSPass(*SI, N); > + } > + } > +#else > + std::vector > Worklist; > + Worklist.push_back(std::make_pair(V, 0U)); > + while (!Worklist.empty()) { > + BasicBlock *BB = Worklist.back().first; > + unsigned NextSucc = Worklist.back().second; > + > + // First time we visited this BB? > + if (NextSucc == 0) { > + InfoRec &BBInfo = Info[BB]; > + BBInfo.Semi = ++N; > + BBInfo.Label = BB; > + > + Vertex.push_back(BB); // Vertex[n] = V; > + //BBInfo[V].Ancestor = 0; // Ancestor[n] = 0 > + //BBInfo[V].Child = 0; // Child[v] = 0 > + BBInfo.Size = 1; // Size[v] = 1 > + } > + > + // If we are done with this block, remove it from the worklist. > + if (NextSucc == BB->getTerminator()->getNumSuccessors()) { > + Worklist.pop_back(); > + continue; > + } > + > + // Otherwise, increment the successor number for the next time > we get to it. > + ++Worklist.back().second; > + > + // Visit the successor next, if it isn't already visited. > + BasicBlock *Succ = BB->getTerminator()->getSuccessor(NextSucc); > + > + InfoRec &SuccVInfo = Info[Succ]; > + if (SuccVInfo.Semi == 0) { > + SuccVInfo.Parent = BB; > + Worklist.push_back(std::make_pair(Succ, 0U)); > + } > + } > +#endif > + return N; > +} > + > // NewBB is split and now it has one successor. Update dominator > tree to > // reflect this change. > void DominatorTree::splitBlock(BasicBlock *NewBB) { > @@ -146,243 +197,6 @@ > } > } > > -unsigned DominatorTree::DFSPass(BasicBlock *V, unsigned N) { > - // This is more understandable as a recursive algorithm, but we > can't use the > - // recursive algorithm due to stack depth issues. Keep it here for > - // documentation purposes. > -#if 0 > - InfoRec &VInfo = Info[Roots[i]]; > - VInfo.Semi = ++N; > - VInfo.Label = V; > - > - Vertex.push_back(V); // Vertex[n] = V; > - //Info[V].Ancestor = 0; // Ancestor[n] = 0 > - //Info[V].Child = 0; // Child[v] = 0 > - VInfo.Size = 1; // Size[v] = 1 > - > - for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E; > ++SI) { > - InfoRec &SuccVInfo = Info[*SI]; > - if (SuccVInfo.Semi == 0) { > - SuccVInfo.Parent = V; > - N = DFSPass(*SI, N); > - } > - } > -#else > - std::vector > Worklist; > - Worklist.push_back(std::make_pair(V, 0U)); > - while (!Worklist.empty()) { > - BasicBlock *BB = Worklist.back().first; > - unsigned NextSucc = Worklist.back().second; > - > - // First time we visited this BB? > - if (NextSucc == 0) { > - InfoRec &BBInfo = Info[BB]; > - BBInfo.Semi = ++N; > - BBInfo.Label = BB; > - > - Vertex.push_back(BB); // Vertex[n] = V; > - //BBInfo[V].Ancestor = 0; // Ancestor[n] = 0 > - //BBInfo[V].Child = 0; // Child[v] = 0 > - BBInfo.Size = 1; // Size[v] = 1 > - } > - > - // If we are done with this block, remove it from the worklist. > - if (NextSucc == BB->getTerminator()->getNumSuccessors()) { > - Worklist.pop_back(); > - continue; > - } > - > - // Otherwise, increment the successor number for the next time > we get to it. > - ++Worklist.back().second; > - > - // Visit the successor next, if it isn't already visited. > - BasicBlock *Succ = BB->getTerminator()->getSuccessor(NextSucc); > - > - InfoRec &SuccVInfo = Info[Succ]; > - if (SuccVInfo.Semi == 0) { > - SuccVInfo.Parent = BB; > - Worklist.push_back(std::make_pair(Succ, 0U)); > - } > - } > -#endif > - return N; > -} > - > -void DominatorTree::Compress(BasicBlock *VIn) { > - > - std::vector Work; > - SmallPtrSet Visited; > - BasicBlock *VInAncestor = Info[VIn].Ancestor; > - InfoRec &VInVAInfo = Info[VInAncestor]; > - > - if (VInVAInfo.Ancestor != 0) > - Work.push_back(VIn); > - > - while (!Work.empty()) { > - BasicBlock *V = Work.back(); > - InfoRec &VInfo = Info[V]; > - BasicBlock *VAncestor = VInfo.Ancestor; > - InfoRec &VAInfo = Info[VAncestor]; > - > - // Process Ancestor first > - if (Visited.insert(VAncestor) && > - VAInfo.Ancestor != 0) { > - Work.push_back(VAncestor); > - continue; > - } > - Work.pop_back(); > - > - // Update VInfo based on Ancestor info > - if (VAInfo.Ancestor == 0) > - continue; > - BasicBlock *VAncestorLabel = VAInfo.Label; > - BasicBlock *VLabel = VInfo.Label; > - if (Info[VAncestorLabel].Semi < Info[VLabel].Semi) > - VInfo.Label = VAncestorLabel; > - VInfo.Ancestor = VAInfo.Ancestor; > - } > -} > - > -BasicBlock *DominatorTree::Eval(BasicBlock *V) { > - InfoRec &VInfo = Info[V]; > -#if !BALANCE_IDOM_TREE > - // Higher-complexity but faster implementation > - if (VInfo.Ancestor == 0) > - return V; > - Compress(V); > - return VInfo.Label; > -#else > - // Lower-complexity but slower implementation > - if (VInfo.Ancestor == 0) > - return VInfo.Label; > - Compress(V); > - BasicBlock *VLabel = VInfo.Label; > - > - BasicBlock *VAncestorLabel = Info[VInfo.Ancestor].Label; > - if (Info[VAncestorLabel].Semi >= Info[VLabel].Semi) > - return VLabel; > - else > - return VAncestorLabel; > -#endif > -} > - > -void DominatorTree::Link(BasicBlock *V, BasicBlock *W, InfoRec > &WInfo){ > -#if !BALANCE_IDOM_TREE > - // Higher-complexity but faster implementation > - WInfo.Ancestor = V; > -#else > - // Lower-complexity but slower implementation > - BasicBlock *WLabel = WInfo.Label; > - unsigned WLabelSemi = Info[WLabel].Semi; > - BasicBlock *S = W; > - InfoRec *SInfo = &Info[S]; > - > - BasicBlock *SChild = SInfo->Child; > - InfoRec *SChildInfo = &Info[SChild]; > - > - while (WLabelSemi < Info[SChildInfo->Label].Semi) { > - BasicBlock *SChildChild = SChildInfo->Child; > - if (SInfo->Size+Info[SChildChild].Size >= 2*SChildInfo->Size) { > - SChildInfo->Ancestor = S; > - SInfo->Child = SChild = SChildChild; > - SChildInfo = &Info[SChild]; > - } else { > - SChildInfo->Size = SInfo->Size; > - S = SInfo->Ancestor = SChild; > - SInfo = SChildInfo; > - SChild = SChildChild; > - SChildInfo = &Info[SChild]; > - } > - } > - > - InfoRec &VInfo = Info[V]; > - SInfo->Label = WLabel; > - > - assert(V != W && "The optimization here will not work in this > case!"); > - unsigned WSize = WInfo.Size; > - unsigned VSize = (VInfo.Size += WSize); > - > - if (VSize < 2*WSize) > - std::swap(S, VInfo.Child); > - > - while (S) { > - SInfo = &Info[S]; > - SInfo->Ancestor = V; > - S = SInfo->Child; > - } > -#endif > -} > - > -void DominatorTree::calculate(Function &F) { > - BasicBlock* Root = Roots[0]; > - > - // Add a node for the root... > - DomTreeNodes[Root] = RootNode = new DomTreeNode(Root, 0); > - > - Vertex.push_back(0); > - > - // Step #1: Number blocks in depth-first order and initialize > variables used > - // in later stages of the algorithm. > - unsigned N = DFSPass(Root, 0); > - > - for (unsigned i = N; i >= 2; --i) { > - BasicBlock *W = Vertex[i]; > - InfoRec &WInfo = Info[W]; > - > - // Step #2: Calculate the semidominators of all vertices > - for (pred_iterator PI = pred_begin(W), E = pred_end(W); PI != > E; ++PI) > - if (Info.count(*PI)) { // Only if this predecessor is > reachable! > - unsigned SemiU = Info[Eval(*PI)].Semi; > - if (SemiU < WInfo.Semi) > - WInfo.Semi = SemiU; > - } > - > - Info[Vertex[WInfo.Semi]].Bucket.push_back(W); > - > - BasicBlock *WParent = WInfo.Parent; > - Link(WParent, W, WInfo); > - > - // Step #3: Implicitly define the immediate dominator of vertices > - std::vector &WParentBucket = Info[WParent].Bucket; > - while (!WParentBucket.empty()) { > - BasicBlock *V = WParentBucket.back(); > - WParentBucket.pop_back(); > - BasicBlock *U = Eval(V); > - IDoms[V] = Info[U].Semi < Info[V].Semi ? U : WParent; > - } > - } > - > - // Step #4: Explicitly define the immediate dominator of each > vertex > - for (unsigned i = 2; i <= N; ++i) { > - BasicBlock *W = Vertex[i]; > - BasicBlock *&WIDom = IDoms[W]; > - if (WIDom != Vertex[Info[W].Semi]) > - WIDom = IDoms[WIDom]; > - } > - > - // Loop over all of the reachable blocks in the function... > - for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) > - if (BasicBlock *ImmDom = getIDom(I)) { // Reachable block. > - DomTreeNode *BBNode = DomTreeNodes[I]; > - if (BBNode) continue; // Haven't calculated this node yet? > - > - // Get or calculate the node for the immediate dominator > - DomTreeNode *IDomNode = getNodeForBlock(ImmDom); > - > - // Add a new tree node for this BasicBlock, and link it as a > child of > - // IDomNode > - DomTreeNode *C = new DomTreeNode(I, IDomNode); > - DomTreeNodes[I] = IDomNode->addChild(C); > - } > - > - // Free temporary memory used to construct idom's > - Info.clear(); > - IDoms.clear(); > - std::vector().swap(Vertex); > - > - updateDFSNumbers(); > -} > - > void DominatorTreeBase::updateDFSNumbers() { > unsigned DFSNum = 0; > > @@ -462,6 +276,21 @@ > RootNode = 0; > } > > +DomTreeNode *DominatorTreeBase::getNodeForBlock(BasicBlock *BB) { > + if (DomTreeNode *BBNode = DomTreeNodes[BB]) > + return BBNode; > + > + // Haven't calculated this node yet? Get or calculate the node > for the > + // immediate dominator. > + BasicBlock *IDom = getIDom(BB); > + DomTreeNode *IDomNode = getNodeForBlock(IDom); > + > + // Add a new tree node for this BasicBlock, and link it as a > child of > + // IDomNode > + DomTreeNode *C = new DomTreeNode(BB, IDomNode); > + return DomTreeNodes[BB] = IDomNode->addChild(C); > +} > + > /// findNearestCommonDominator - Find nearest common dominator > basic block > /// for basic block A and B. If there is no such block then return > NULL. > BasicBlock *DominatorTreeBase::findNearestCommonDominator > (BasicBlock *A, > @@ -525,21 +354,6 @@ > } > } > > -DomTreeNode *DominatorTree::getNodeForBlock(BasicBlock *BB) { > - if (DomTreeNode *BBNode = DomTreeNodes[BB]) > - return BBNode; > - > - // Haven't calculated this node yet? Get or calculate the node > for the > - // immediate dominator. > - BasicBlock *IDom = getIDom(BB); > - DomTreeNode *IDomNode = getNodeForBlock(IDom); > - > - // Add a new tree node for this BasicBlock, and link it as a > child of > - // IDomNode > - DomTreeNode *C = new DomTreeNode(BB, IDomNode); > - return DomTreeNodes[BB] = IDomNode->addChild(C); > -} > - > static std::ostream &operator<<(std::ostream &o, const DomTreeNode > *Node) { > if (Node->getBlock()) > WriteAsOperand(o, Node->getBlock(), false); > @@ -599,7 +413,7 @@ > bool DominatorTree::runOnFunction(Function &F) { > reset(); // Reset from the last time we were run... > Roots.push_back(&F.getEntryBlock()); > - calculate(F); > + DTcalculate(*this, F); > return false; > } > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From djg at cray.com Mon Sep 24 09:44:26 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 24 Sep 2007 16:44:26 -0000 Subject: [llvm-commits] [llvm] r42265 - /llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <200709241644.l8OGiQPC024893@zion.cs.uiuc.edu> Author: djg Date: Mon Sep 24 11:44:26 2007 New Revision: 42265 URL: http://llvm.org/viewvc/llvm-project?rev=42265&view=rev Log: The code that used the StartLabelId label was removed, so remove the code that creates the label too. 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=42265&r1=42264&r2=42265&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Mon Sep 24 11:44:26 2007 @@ -1278,18 +1278,12 @@ MachineBasicBlock::iterator MBBI = MBB.begin(); // Prepare for frame info. - unsigned FrameLabelId = 0, StartLabelId = 0; + unsigned FrameLabelId = 0; // Get the number of bytes to allocate from the FrameInfo uint64_t StackSize = MFI->getStackSize(); uint64_t NumBytes = StackSize - X86FI->getCalleeSavedFrameSize(); - if (MMI && MMI->needsFrameInfo()) { - // Mark function start - StartLabelId = MMI->NextLabelID(); - BuildMI(MBB, MBBI, TII.get(X86::LABEL)).addImm(StartLabelId); - } - if (hasFP(MF)) { // Get the offset of the stack slot for the EBP register... which is // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. From tonic at nondot.org Mon Sep 24 10:14:53 2007 From: tonic at nondot.org (Tanya Lattner) Date: Mon, 24 Sep 2007 17:14:53 -0000 Subject: [llvm-commits] [llvm] r42266 - /llvm/trunk/test/CFrontend/2007-09-17-WeakRef.c Message-ID: <200709241714.l8OHEr6s025705@zion.cs.uiuc.edu> Author: tbrethou Date: Mon Sep 24 12:14:53 2007 New Revision: 42266 URL: http://llvm.org/viewvc/llvm-project?rev=42266&view=rev Log: XFAIL for llvm-gcc4.0 Modified: llvm/trunk/test/CFrontend/2007-09-17-WeakRef.c Modified: llvm/trunk/test/CFrontend/2007-09-17-WeakRef.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/2007-09-17-WeakRef.c?rev=42266&r1=42265&r2=42266&view=diff ============================================================================== --- llvm/trunk/test/CFrontend/2007-09-17-WeakRef.c (original) +++ llvm/trunk/test/CFrontend/2007-09-17-WeakRef.c Mon Sep 24 12:14:53 2007 @@ -1,6 +1,6 @@ // RUN: %llvmgcc -O1 -S %s -o - | grep icmp // PR1678 - +// XFAIL: llvmgcc4.0.1 extern void B (void); static __typeof(B) A __attribute__ ((__weakref__("B"))); int active (void) From dberlin at dberlin.org Mon Sep 24 10:52:27 2007 From: dberlin at dberlin.org (Daniel Berlin) Date: Mon, 24 Sep 2007 17:52:27 -0000 Subject: [llvm-commits] [llvm] r42267 - /llvm/trunk/docs/ProgrammersManual.html Message-ID: <200709241752.l8OHqROe026570@zion.cs.uiuc.edu> Author: dannyb Date: Mon Sep 24 12:52:25 2007 New Revision: 42267 URL: http://llvm.org/viewvc/llvm-project?rev=42267&view=rev Log: Add section on bit containers. (Not the most well written stuff in the universe :P) Modified: llvm/trunk/docs/ProgrammersManual.html Modified: llvm/trunk/docs/ProgrammersManual.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ProgrammersManual.html?rev=42267&r1=42266&r2=42267&view=diff ============================================================================== --- llvm/trunk/docs/ProgrammersManual.html (original) +++ llvm/trunk/docs/ProgrammersManual.html Mon Sep 24 12:52:25 2007 @@ -77,6 +77,11 @@
  4. <map>
  5. Other Map-Like Container Options
  6. +
  7. BitVector-like containers +
  8. Helpful Hints for Common Operations @@ -705,6 +710,11 @@ iteration, but do not support efficient look-up based on a key.
  9. +
  10. a bit container provides an efficient way to store and + perform set operations on sets of numeric id's, while automatically + eliminating duplicates. Bit containers require a maximum of 1 bit for each + identifier you want to store. +
  11. @@ -1276,6 +1286,45 @@ + +

    + +
    +Unlike the other containers, there are only two bit storage containers, and when +to use each is relatively straightforward. +
    + + + + +
    +

    The BitVector container provides a fixed size set of bits for manipulation. +It supports individual bit setting/testing, as well as set operations. The set +operations take time O(size of bitvector), but operations are performed one word +at a time, instead of one bit at a time. This makes the BitVector very fast for +set operations compared to other containers. Use the BitVector when you expect +the number of set bits to be high (IE a dense set). +

    +
    + + + + +
    +

    The SparseBitVector container is much like BitVector, with one major +difference: Only the bits that are set, are stored. This makes the +SparseBitVector much more space efficient than BitVector when the set is sparse, +as well as making set operations O(number of set bits) instead of O(size of +universe). The downside to the SparseBitVector is that setting and testing of random bits is O(N), and on large SparseBitVectors, this can be slower than BitVector. In our implementation, setting or testing bits in sorted order +(either forwards or reverse) is O(1) worst case. Testing and setting bits within 128 bits (depends on size) of the current bit is also O(1). As a general statement, testing/setting bits in a SparseBitVector is O(distance away from last set bit). +

    +
    From baldrick at free.fr Mon Sep 24 11:59:54 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 24 Sep 2007 20:59:54 +0200 Subject: [llvm-commits] [llvm] r42266 - /llvm/trunk/test/CFrontend/2007-09-17-WeakRef.c In-Reply-To: <200709241714.l8OHEr6s025705@zion.cs.uiuc.edu> References: <200709241714.l8OHEr6s025705@zion.cs.uiuc.edu> Message-ID: <200709242059.56590.baldrick@free.fr> Hi Tanya, > XFAIL for llvm-gcc4.0 I'm pretty sure this only failed for llvm-gcc-4.2 but passed with 4.0... Did you mean 4.2 here? Thanks, Duncan. From tonic at nondot.org Mon Sep 24 14:12:26 2007 From: tonic at nondot.org (Tanya M. Lattner) Date: Mon, 24 Sep 2007 14:12:26 -0700 (PDT) Subject: [llvm-commits] [llvm] r42266 - /llvm/trunk/test/CFrontend/2007-09-17-WeakRef.c In-Reply-To: <200709242059.56590.baldrick@free.fr> References: <200709241714.l8OHEr6s025705@zion.cs.uiuc.edu> <200709242059.56590.baldrick@free.fr> Message-ID: > I'm pretty sure this only failed for llvm-gcc-4.2 > but passed with 4.0... Did you mean 4.2 here? No. This fails for me on llvm-gcc4.0. -Tanya > > Thanks, > > Duncan. > From djg at cray.com Mon Sep 24 12:25:06 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 24 Sep 2007 19:25:06 -0000 Subject: [llvm-commits] [llvm] r42268 - /llvm/trunk/lib/Target/X86/X86InstrInfo.td Message-ID: <200709241925.l8OJP6Gp029149@zion.cs.uiuc.edu> Author: djg Date: Mon Sep 24 14:25:06 2007 New Revision: 42268 URL: http://llvm.org/viewvc/llvm-project?rev=42268&view=rev Log: Fix the syntax for the .loc directive in preparation for using it. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=42268&r1=42267&r2=42268&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon Sep 24 14:25:06 2007 @@ -2434,7 +2434,7 @@ def DWARF_LOC : I<0, Pseudo, (outs), (ins i32imm:$line, i32imm:$col, i32imm:$file), - "; .loc ${file:debug}, ${line:debug}, ${col:debug}", + ".loc\t${file:debug} ${line:debug} ${col:debug}", [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>; From dberlin at dberlin.org Mon Sep 24 12:45:50 2007 From: dberlin at dberlin.org (Daniel Berlin) Date: Mon, 24 Sep 2007 19:45:50 -0000 Subject: [llvm-commits] [llvm] r42269 - in /llvm/trunk: include/llvm/ADT/DenseMap.h include/llvm/ADT/SparseBitVector.h lib/Analysis/IPA/Andersens.cpp Message-ID: <200709241945.l8OJjo1M029802@zion.cs.uiuc.edu> Author: dannyb Date: Mon Sep 24 14:45:49 2007 New Revision: 42269 URL: http://llvm.org/viewvc/llvm-project?rev=42269&view=rev Log: Implement offline variable substitution in order to reduce memory and time usage. Fixup operator == to make this work, and add a resize method to DenseMap so we can resize our hashtable once we know how big it should be. Modified: llvm/trunk/include/llvm/ADT/DenseMap.h llvm/trunk/include/llvm/ADT/SparseBitVector.h llvm/trunk/lib/Analysis/IPA/Andersens.cpp Modified: llvm/trunk/include/llvm/ADT/DenseMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=42269&r1=42268&r2=42269&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/DenseMap.h (original) +++ llvm/trunk/include/llvm/ADT/DenseMap.h Mon Sep 24 14:45:49 2007 @@ -99,6 +99,9 @@ bool empty() const { return NumEntries == 0; } unsigned size() const { return NumEntries; } + + /// Grow the densemap so that it has at least Size buckets. Does not shrink + void resize(size_t Size) { grow(Size); } void clear() { // If the capacity of the array is huge, and the # elements used is small, @@ -228,7 +231,7 @@ // causing infinite loops in lookup. if (NumEntries*4 >= NumBuckets*3 || NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) { - this->grow(); + this->grow(NumBuckets * 2); LookupBucketFor(Key, TheBucket); } ++NumEntries; @@ -310,12 +313,13 @@ new (&Buckets[i].first) KeyT(EmptyKey); } - void grow() { + void grow(unsigned AtLeast) { unsigned OldNumBuckets = NumBuckets; BucketT *OldBuckets = Buckets; // Double the number of buckets. - NumBuckets <<= 1; + while (NumBuckets <= AtLeast) + NumBuckets <<= 1; NumTombstones = 0; Buckets = reinterpret_cast(new char[sizeof(BucketT)*NumBuckets]); Modified: llvm/trunk/include/llvm/ADT/SparseBitVector.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SparseBitVector.h?rev=42269&r1=42268&r2=42269&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/SparseBitVector.h (original) +++ llvm/trunk/include/llvm/ADT/SparseBitVector.h Mon Sep 24 14:45:49 2007 @@ -75,7 +75,6 @@ } friend struct ilist_traits >; - public: explicit SparseBitVectorElement(unsigned Idx) { ElementIndex = Idx; @@ -287,6 +286,14 @@ } BecameZero = allzero; } + // Get a hash value for this element; + uint64_t getHashValue() const { + uint64_t HashVal = 0; + for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) { + HashVal ^= Bits[i]; + } + return HashVal; + } }; template @@ -544,22 +551,20 @@ return false; } - bool operator!=(const SparseBitVector &RHS) { + bool operator!=(const SparseBitVector &RHS) const { return !(*this == RHS); } - bool operator==(const SparseBitVector &RHS) { + bool operator==(const SparseBitVector &RHS) const { ElementListConstIter Iter1 = Elements.begin(); ElementListConstIter Iter2 = RHS.Elements.begin(); - while (Iter2 != RHS.Elements.end()) { - if (Iter1->index() != Iter2->index() - || *Iter1 != *Iter2) + for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end(); + ++Iter1, ++Iter2) { + if (*Iter1 != *Iter2) return false; - ++Iter1; - ++Iter2; } - return Iter1 == Elements.end(); + return Iter1 == Elements.end() && Iter2 == RHS.Elements.end(); } // Union our bitmap with the RHS and return true if we changed. @@ -789,6 +794,17 @@ return iterator(this, ~0); } + // Get a hash value for this bitmap. + uint64_t getHashValue() const { + uint64_t HashVal = 0; + for (ElementListConstIter Iter = Elements.begin(); + Iter != Elements.end(); + ++Iter) { + HashVal ^= Iter->index(); + HashVal ^= Iter->getHashValue(); + } + return HashVal; + } }; // Convenience functions to allow Or and And without dereferencing in the user @@ -828,9 +844,10 @@ for (bi = LHS.begin(); bi != LHS.end(); ++bi) { out << *bi << " "; } - out << "\n"; + out << " ]\n"; } - } + + #endif Modified: llvm/trunk/lib/Analysis/IPA/Andersens.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/Andersens.cpp?rev=42269&r1=42268&r2=42269&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IPA/Andersens.cpp (original) +++ llvm/trunk/lib/Analysis/IPA/Andersens.cpp Mon Sep 24 14:45:49 2007 @@ -16,7 +16,8 @@ // This algorithm is implemented as three stages: // 1. Object identification. // 2. Inclusion constraint identification. -// 3. Inclusion constraint solving. +// 3. Offline constraint graph optimization +// 4. Inclusion constraint solving. // // The object identification stage identifies all of the memory objects in the // program, which includes globals, heap allocated objects, and stack allocated @@ -29,20 +30,25 @@ // B can point to. Constraints can handle copies, loads, and stores, and // address taking. // +// The Offline constraint graph optimization portion includes offline variable +// substitution algorithms intended to pointer and location equivalences. +// Pointer equivalences are those pointers that will have the same points-to +// sets, and location equivalences are those variables that always appear +// together in points-to sets. +// // The inclusion constraint solving phase iteratively propagates the inclusion // constraints until a fixed point is reached. This is an O(N^3) algorithm. // // Function constraints are handled as if they were structs with X fields. // Thus, an access to argument X of function Y is an access to node index // getNode(Y) + X. This representation allows handling of indirect calls -// without any issues. To wit, an indirect call Y(a,b) is equivalence to +// without any issues. To wit, an indirect call Y(a,b) is equivalent to // *(Y + 1) = a, *(Y + 2) = b. // The return node for a function is always located at getNode(F) + // CallReturnPos. The arguments start at getNode(F) + CallArgPos. // // Future Improvements: -// Offline variable substitution, offline detection of online -// cycles. Use of BDD's. +// Offline detection of online cycles. Use of BDD's. //===----------------------------------------------------------------------===// #define DEBUG_TYPE "anders-aa" @@ -59,6 +65,7 @@ #include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/SparseBitVector.h" +#include "llvm/ADT/DenseMap.h" #include #include #include @@ -66,18 +73,42 @@ #include using namespace llvm; -STATISTIC(NumIters , "Number of iterations to reach convergence"); -STATISTIC(NumConstraints , "Number of constraints"); -STATISTIC(NumNodes , "Number of nodes"); -STATISTIC(NumUnified , "Number of variables unified"); +STATISTIC(NumIters , "Number of iterations to reach convergence"); +STATISTIC(NumConstraints, "Number of constraints"); +STATISTIC(NumNodes , "Number of nodes"); +STATISTIC(NumUnified , "Number of variables unified"); namespace { const unsigned SelfRep = (unsigned)-1; const unsigned Unvisited = (unsigned)-1; // Position of the function return node relative to the function node. - const unsigned CallReturnPos = 2; + const unsigned CallReturnPos = 1; // Position of the function call node relative to the function node. - const unsigned CallFirstArgPos = 3; + const unsigned CallFirstArgPos = 2; + + struct BitmapKeyInfo { + static inline SparseBitVector<> *getEmptyKey() { + return reinterpret_cast *>(-1); + } + static inline SparseBitVector<> *getTombstoneKey() { + return reinterpret_cast *>(-2); + } + static unsigned getHashValue(const SparseBitVector<> *bitmap) { + return bitmap->getHashValue(); + } + static bool isEqual(const SparseBitVector<> *LHS, + const SparseBitVector<> *RHS) { + if (LHS == RHS) + return true; + else if (LHS == getEmptyKey() || RHS == getEmptyKey() + || LHS == getTombstoneKey() || RHS == getTombstoneKey()) + return false; + + return *LHS == *RHS; + } + + static bool isPod() { return true; } + }; class VISIBILITY_HIDDEN Andersens : public ModulePass, public AliasAnalysis, private InstVisitor { @@ -89,7 +120,7 @@ /// 'store' for statements like "*A = B", and AddressOf for statements like /// A = alloca; The Offset is applied as *(A + K) = B for stores, /// A = *(B + K) for loads, and A = B + K for copies. It is - /// illegal on addressof constraints (Because it is statically + /// illegal on addressof constraints (because it is statically /// resolvable to A = &C where C = B + K) struct Constraint { @@ -105,29 +136,53 @@ } }; - // Node class - This class is used to represent a node - // in the constraint graph. Due to various optimizations, - // not always the case that there is a mapping from a Node to a - // Value. In particular, we add artificial - // Node's that represent the set of pointed-to variables - // shared for each location equivalent Node. + // Node class - This class is used to represent a node in the constraint + // graph. Due to various optimizations, not always the case that there is a + // mapping from a Node to a Value. In particular, we add artificial Node's + // that represent the set of pointed-to variables shared for each location + // equivalent Node. struct Node { - Value *Val; + Value *Val; SparseBitVector<> *Edges; SparseBitVector<> *PointsTo; SparseBitVector<> *OldPointsTo; bool Changed; std::list Constraints; - // Nodes in cycles (or in equivalence classes) are united - // together using a standard union-find representation with path - // compression. NodeRep gives the index into GraphNodes - // representative for this one. - unsigned NodeRep; public: - - Node() : Val(0), Edges(0), PointsTo(0), OldPointsTo(0), Changed(false), - NodeRep(SelfRep) { - } + // Pointer and location equivalence labels + unsigned PointerEquivLabel; + unsigned LocationEquivLabel; + // Predecessor edges, both real and implicit + SparseBitVector<> *PredEdges; + SparseBitVector<> *ImplicitPredEdges; + // Set of nodes that point to us, only use for location equivalence. + SparseBitVector<> *PointedToBy; + // Number of incoming edges, used during variable substitution to early + // free the points-to sets + unsigned NumInEdges; + // True if our ponits-to set is in the Set2PEClass map + bool StoredInHash; + // True if our node has no indirect constraints (Complex or otherwise) + bool Direct; + // True if the node is address taken, *or* it is part of a group of nodes + // that must be kept together. This is set to true for functions and + // their arg nodes, which must be kept at the same position relative to + // their base function node. + // kept at the same position relative to their base function node. + bool AddressTaken; + + // Nodes in cycles (or in equivalence classes) are united together using a + // standard union-find representation with path compression. NodeRep + // gives the index into GraphNodes for the representative Node. + unsigned NodeRep; + public: + + Node(bool direct = true) : + Val(0), Edges(0), PointsTo(0), OldPointsTo(0), Changed(false), + PointerEquivLabel(0), LocationEquivLabel(0), PredEdges(0), + ImplicitPredEdges(0), PointedToBy(0), NumInEdges(0), + StoredInHash(false), Direct(direct), AddressTaken(false), + NodeRep(SelfRep) { } Node *setValue(Value *V) { assert(Val == 0 && "Value already set for this node!"); @@ -163,28 +218,28 @@ /// ValueNodes - This map indicates the Node that a particular Value* is /// represented by. This contains entries for all pointers. - std::map ValueNodes; + DenseMap ValueNodes; /// ObjectNodes - This map contains entries for each memory object in the /// program: globals, alloca's and mallocs. - std::map ObjectNodes; + DenseMap ObjectNodes; /// ReturnNodes - This map contains an entry for each function in the /// program that returns a value. - std::map ReturnNodes; + DenseMap ReturnNodes; /// VarargNodes - This map contains the entry used to represent all pointers /// passed through the varargs portion of a function call for a particular /// function. An entry is not present in this map for functions that do not /// take variable arguments. - std::map VarargNodes; + DenseMap VarargNodes; /// Constraints - This vector contains a list of all of the constraints /// identified by the program. std::vector Constraints; - // Map from graph node to maximum K value that is allowed (For functions, + // Map from graph node to maximum K value that is allowed (for functions, // this is equivalent to the number of arguments + CallFirstArgPos) std::map MaxK; @@ -193,9 +248,10 @@ enum { UniversalSet = 0, NullPtr = 1, - NullObject = 2 + NullObject = 2, + NumberSpecialNodes }; - // Stack for Tarjans + // Stack for Tarjan's std::stack SCCStack; // Topological Index -> Graph node std::vector Topo2Node; @@ -209,6 +265,34 @@ unsigned DFSNumber; unsigned RPONumber; + // Offline variable substitution related things + + // Temporary rep storage, used because we can't collapse SCC's in the + // predecessor graph by uniting the variables permanently, we can only do so + // for the successor graph. + std::vector VSSCCRep; + // Mapping from node to whether we have visited it during SCC finding yet. + std::vector Node2Visited; + // During variable substitution, we create unknowns to represent the unknown + // value that is a dereference of a variable. These nodes are known as + // "ref" nodes (since they represent the value of dereferences). + unsigned FirstRefNode; + // During HVN, we create represent address taken nodes as if they were + // unknown (since HVN, unlike HU, does not evaluate unions). + unsigned FirstAdrNode; + // Current pointer equivalence class number + unsigned PEClass; + // Mapping from points-to sets to equivalence classes + typedef DenseMap *, unsigned, BitmapKeyInfo> BitVectorMap; + BitVectorMap Set2PEClass; + // Mapping from pointer equivalences to the representative node. -1 if we + // have no representative node for this pointer equivalence class yet. + std::vector PEClass2Node; + // Mapping from pointer equivalences to representative node. This includes + // pointer equivalent but not location equivalent variables. -1 if we have + // no representative node for this pointer equivalence class yet. + std::vector PENLEClass2Node; + public: static char ID; Andersens() : ModulePass((intptr_t)&ID) {} @@ -217,7 +301,11 @@ InitializeAliasAnalysis(this); IdentifyObjects(M); CollectConstraints(M); +#undef DEBUG_TYPE +#define DEBUG_TYPE "anders-aa-constraints" DEBUG(PrintConstraints()); +#undef DEBUG_TYPE +#define DEBUG_TYPE "anders-aa" SolveConstraints(); DEBUG(PrintPointsToGraph()); @@ -275,7 +363,7 @@ if (!isa(C)) return getNodeForConstantPointer(C); - std::map::iterator I = ValueNodes.find(V); + DenseMap::iterator I = ValueNodes.find(V); if (I == ValueNodes.end()) { #ifndef NDEBUG V->dump(); @@ -288,7 +376,7 @@ /// getObject - Return the node corresponding to the memory object for the /// specified global or allocation instruction. unsigned getObject(Value *V) { - std::map::iterator I = ObjectNodes.find(V); + DenseMap::iterator I = ObjectNodes.find(V); assert(I != ObjectNodes.end() && "Value does not have an object in the points-to graph!"); return I->second; @@ -297,7 +385,7 @@ /// getReturnNode - Return the node representing the return value for the /// specified function. unsigned getReturnNode(Function *F) { - std::map::iterator I = ReturnNodes.find(F); + DenseMap::iterator I = ReturnNodes.find(F); assert(I != ReturnNodes.end() && "Function does not return a value!"); return I->second; } @@ -305,7 +393,7 @@ /// getVarargNode - Return the node representing the variable arguments /// formal for the specified function. unsigned getVarargNode(Function *F) { - std::map::iterator I = VarargNodes.find(F); + DenseMap::iterator I = VarargNodes.find(F); assert(I != VarargNodes.end() && "Function does not take var args!"); return I->second; } @@ -325,9 +413,18 @@ void CollectConstraints(Module &M); bool AnalyzeUsesOfFunction(Value *); void CreateConstraintGraph(); + void OptimizeConstraints(); + unsigned FindEquivalentNode(unsigned, unsigned); + void ClumpAddressTaken(); + void RewriteConstraints(); + void HU(); + void HVN(); + void UnitePointerEquivalences(); void SolveConstraints(); void QueryNode(unsigned Node); - + void Condense(unsigned Node); + void HUValNum(unsigned Node); + void HVNValNum(unsigned Node); unsigned getNodeForConstantPointer(Constant *C); unsigned getNodeForConstantPointerTarget(Constant *C); void AddGlobalInitializerConstraints(unsigned, Constant *C); @@ -339,6 +436,8 @@ void PrintNode(Node *N); void PrintConstraints(); + void PrintConstraint(const Constraint &); + void PrintLabels(); void PrintPointsToGraph(); //===------------------------------------------------------------------===// @@ -506,7 +605,6 @@ // The function itself is a memory object. unsigned First = NumObjects; ValueNodes[F] = NumObjects++; - ObjectNodes[F] = NumObjects++; if (isa(F->getFunctionType()->getReturnType())) ReturnNodes[F] = NumObjects++; if (F->getFunctionType()->isVarArg()) @@ -516,10 +614,11 @@ // Add nodes for all of the incoming pointer arguments. for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) - if (isa(I->getType())) - ValueNodes[I] = NumObjects++; + { + if (isa(I->getType())) + ValueNodes[I] = NumObjects++; + } MaxK[First] = NumObjects - First; - MaxK[First + 1] = NumObjects - First - 1; // Scan the function body, creating a memory object for each heap/stack // allocation in the body of the function and a node to represent all @@ -796,11 +895,6 @@ } for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { - // Make the function address point to the function object. - unsigned ObjectIndex = getObject(F); - GraphNodes[ObjectIndex].setValue(F); - Constraints.push_back(Constraint(Constraint::AddressOf, getNodeValue(*F), - ObjectIndex)); // Set up the return value node. if (isa(F->getFunctionType()->getReturnType())) GraphNodes[getReturnNode(F)].setValue(F); @@ -1091,8 +1185,736 @@ return Result; } -// Create the constraint graph used for solving points-to analysis. -// +void dumpToDOUT(SparseBitVector<> *bitmap) { + dump(*bitmap, DOUT); +} + + +/// Clump together address taken variables so that the points-to sets use up +/// less space and can be operated on faster. + +void Andersens::ClumpAddressTaken() { +#undef DEBUG_TYPE +#define DEBUG_TYPE "anders-aa-renumber" + std::vector Translate; + std::vector NewGraphNodes; + + Translate.resize(GraphNodes.size()); + unsigned NewPos = 0; + + for (unsigned i = 0; i < Constraints.size(); ++i) { + Constraint &C = Constraints[i]; + if (C.Type == Constraint::AddressOf) { + GraphNodes[C.Src].AddressTaken = true; + } + } + for (unsigned i = 0; i < NumberSpecialNodes; ++i) { + unsigned Pos = NewPos++; + Translate[i] = Pos; + NewGraphNodes.push_back(GraphNodes[i]); + DOUT << "Renumbering node " << i << " to node " << Pos << "\n"; + } + + // I believe this ends up being faster than making two vectors and splicing + // them. + for (unsigned i = NumberSpecialNodes; i < GraphNodes.size(); ++i) { + if (GraphNodes[i].AddressTaken) { + unsigned Pos = NewPos++; + Translate[i] = Pos; + NewGraphNodes.push_back(GraphNodes[i]); + DOUT << "Renumbering node " << i << " to node " << Pos << "\n"; + } + } + + for (unsigned i = NumberSpecialNodes; i < GraphNodes.size(); ++i) { + if (!GraphNodes[i].AddressTaken) { + unsigned Pos = NewPos++; + Translate[i] = Pos; + NewGraphNodes.push_back(GraphNodes[i]); + DOUT << "Renumbering node " << i << " to node " << Pos << "\n"; + } + } + + for (DenseMap::iterator Iter = ValueNodes.begin(); + Iter != ValueNodes.end(); + ++Iter) + Iter->second = Translate[Iter->second]; + + for (DenseMap::iterator Iter = ObjectNodes.begin(); + Iter != ObjectNodes.end(); + ++Iter) + Iter->second = Translate[Iter->second]; + + for (DenseMap::iterator Iter = ReturnNodes.begin(); + Iter != ReturnNodes.end(); + ++Iter) + Iter->second = Translate[Iter->second]; + + for (DenseMap::iterator Iter = VarargNodes.begin(); + Iter != VarargNodes.end(); + ++Iter) + Iter->second = Translate[Iter->second]; + + for (unsigned i = 0; i < Constraints.size(); ++i) { + Constraint &C = Constraints[i]; + C.Src = Translate[C.Src]; + C.Dest = Translate[C.Dest]; + } + + GraphNodes.swap(NewGraphNodes); +#undef DEBUG_TYPE +#define DEBUG_TYPE "anders-aa" +} + +/// The technique used here is described in "Exploiting Pointer and Location +/// Equivalence to Optimize Pointer Analysis. In the 14th International Static +/// Analysis Symposium (SAS), August 2007." It is known as the "HVN" algorithm, +/// and is equivalent to value numbering the collapsed constraint graph without +/// evaluating unions. This is used as a pre-pass to HU in order to resolve +/// first order pointer dereferences and speed up/reduce memory usage of HU. +/// Running both is equivalent to HRU without the iteration +/// HVN in more detail: +/// Imagine the set of constraints was simply straight line code with no loops +/// (we eliminate cycles, so there are no loops), such as: +/// E = &D +/// E = &C +/// E = F +/// F = G +/// G = F +/// Applying value numbering to this code tells us: +/// G == F == E +/// +/// For HVN, this is as far as it goes. We assign new value numbers to every +/// "address node", and every "reference node". +/// To get the optimal result for this, we use a DFS + SCC (since all nodes in a +/// cycle must have the same value number since the = operation is really +/// inclusion, not overwrite), and value number nodes we receive points-to sets +/// before we value our own node. +/// The advantage of HU over HVN is that HU considers the inclusion property, so +/// that if you have +/// E = &D +/// E = &C +/// E = F +/// F = G +/// F = &D +/// G = F +/// HU will determine that G == F == E. HVN will not, because it cannot prove +/// that the points to information ends up being the same because they all +/// receive &D from E anyway. + +void Andersens::HVN() { + DOUT << "Beginning HVN\n"; + // Build a predecessor graph. This is like our constraint graph with the + // edges going in the opposite direction, and there are edges for all the + // constraints, instead of just copy constraints. We also build implicit + // edges for constraints are implied but not explicit. I.E for the constraint + // a = &b, we add implicit edges *a = b. This helps us capture more cycles + for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { + Constraint &C = Constraints[i]; + if (C.Type == Constraint::AddressOf) { + GraphNodes[C.Src].AddressTaken = true; + GraphNodes[C.Src].Direct = false; + + // Dest = &src edge + unsigned AdrNode = C.Src + FirstAdrNode; + if (!GraphNodes[C.Dest].PredEdges) + GraphNodes[C.Dest].PredEdges = new SparseBitVector<>; + GraphNodes[C.Dest].PredEdges->set(AdrNode); + + // *Dest = src edge + unsigned RefNode = C.Dest + FirstRefNode; + if (!GraphNodes[RefNode].ImplicitPredEdges) + GraphNodes[RefNode].ImplicitPredEdges = new SparseBitVector<>; + GraphNodes[RefNode].ImplicitPredEdges->set(C.Src); + } else if (C.Type == Constraint::Load) { + if (C.Offset == 0) { + // dest = *src edge + if (!GraphNodes[C.Dest].PredEdges) + GraphNodes[C.Dest].PredEdges = new SparseBitVector<>; + GraphNodes[C.Dest].PredEdges->set(C.Src + FirstRefNode); + } else { + GraphNodes[C.Dest].Direct = false; + } + } else if (C.Type == Constraint::Store) { + if (C.Offset == 0) { + // *dest = src edge + unsigned RefNode = C.Dest + FirstRefNode; + if (!GraphNodes[RefNode].PredEdges) + GraphNodes[RefNode].PredEdges = new SparseBitVector<>; + GraphNodes[RefNode].PredEdges->set(C.Src); + } + } else { + // Dest = Src edge and *Dest = *Src edge + if (!GraphNodes[C.Dest].PredEdges) + GraphNodes[C.Dest].PredEdges = new SparseBitVector<>; + GraphNodes[C.Dest].PredEdges->set(C.Src); + unsigned RefNode = C.Dest + FirstRefNode; + if (!GraphNodes[RefNode].ImplicitPredEdges) + GraphNodes[RefNode].ImplicitPredEdges = new SparseBitVector<>; + GraphNodes[RefNode].ImplicitPredEdges->set(C.Src + FirstRefNode); + } + } + PEClass = 1; + // Do SCC finding first to condense our predecessor graph + DFSNumber = 0; + Node2DFS.insert(Node2DFS.begin(), GraphNodes.size(), 0); + Node2Deleted.insert(Node2Deleted.begin(), GraphNodes.size(), false); + Node2Visited.insert(Node2Visited.begin(), GraphNodes.size(), false); + + for (unsigned i = 0; i < FirstRefNode; ++i) { + unsigned Node = VSSCCRep[i]; + if (!Node2Visited[Node]) + HVNValNum(Node); + } + for (BitVectorMap::iterator Iter = Set2PEClass.begin(); + Iter != Set2PEClass.end(); + ++Iter) + delete Iter->first; + Set2PEClass.clear(); + Node2DFS.clear(); + Node2Deleted.clear(); + Node2Visited.clear(); + DOUT << "Finished HVN\n"; + +} + +/// This is the workhorse of HVN value numbering. We combine SCC finding at the +/// same time because it's easy. +void Andersens::HVNValNum(unsigned NodeIndex) { + unsigned MyDFS = DFSNumber++; + Node *N = &GraphNodes[NodeIndex]; + Node2Visited[NodeIndex] = true; + Node2DFS[NodeIndex] = MyDFS; + + // First process all our explicit edges + if (N->PredEdges) + for (SparseBitVector<>::iterator Iter = N->PredEdges->begin(); + Iter != N->PredEdges->end(); + ++Iter) { + unsigned j = VSSCCRep[*Iter]; + if (!Node2Deleted[j]) { + if (!Node2Visited[j]) + HVNValNum(j); + if (Node2DFS[NodeIndex] > Node2DFS[j]) + Node2DFS[NodeIndex] = Node2DFS[j]; + } + } + + // Now process all the implicit edges + if (N->ImplicitPredEdges) + for (SparseBitVector<>::iterator Iter = N->ImplicitPredEdges->begin(); + Iter != N->ImplicitPredEdges->end(); + ++Iter) { + unsigned j = VSSCCRep[*Iter]; + if (!Node2Deleted[j]) { + if (!Node2Visited[j]) + HVNValNum(j); + if (Node2DFS[NodeIndex] > Node2DFS[j]) + Node2DFS[NodeIndex] = Node2DFS[j]; + } + } + + // See if we found any cycles + if (MyDFS == Node2DFS[NodeIndex]) { + while (!SCCStack.empty() && Node2DFS[SCCStack.top()] >= MyDFS) { + unsigned CycleNodeIndex = SCCStack.top(); + Node *CycleNode = &GraphNodes[CycleNodeIndex]; + VSSCCRep[CycleNodeIndex] = NodeIndex; + // Unify the nodes + N->Direct &= CycleNode->Direct; + + if (CycleNode->PredEdges) { + if (!N->PredEdges) + N->PredEdges = new SparseBitVector<>; + *(N->PredEdges) |= CycleNode->PredEdges; + delete CycleNode->PredEdges; + CycleNode->PredEdges = NULL; + } + if (CycleNode->ImplicitPredEdges) { + if (!N->ImplicitPredEdges) + N->ImplicitPredEdges = new SparseBitVector<>; + *(N->ImplicitPredEdges) |= CycleNode->ImplicitPredEdges; + delete CycleNode->ImplicitPredEdges; + CycleNode->ImplicitPredEdges = NULL; + } + + SCCStack.pop(); + } + + Node2Deleted[NodeIndex] = true; + + if (!N->Direct) { + GraphNodes[NodeIndex].PointerEquivLabel = PEClass++; + return; + } + + // Collect labels of successor nodes + bool AllSame = true; + unsigned First = ~0; + SparseBitVector<> *Labels = new SparseBitVector<>; + bool Used = false; + + if (N->PredEdges) + for (SparseBitVector<>::iterator Iter = N->PredEdges->begin(); + Iter != N->PredEdges->end(); + ++Iter) { + unsigned j = VSSCCRep[*Iter]; + unsigned Label = GraphNodes[j].PointerEquivLabel; + // Ignore labels that are equal to us or non-pointers + if (j == NodeIndex || Label == 0) + continue; + if (First == (unsigned)~0) + First = Label; + else if (First != Label) + AllSame = false; + Labels->set(Label); + } + + // We either have a non-pointer, a copy of an existing node, or a new node. + // Assign the appropriate pointer equivalence label. + if (Labels->empty()) { + GraphNodes[NodeIndex].PointerEquivLabel = 0; + } else if (AllSame) { + GraphNodes[NodeIndex].PointerEquivLabel = First; + } else { + GraphNodes[NodeIndex].PointerEquivLabel = Set2PEClass[Labels]; + if (GraphNodes[NodeIndex].PointerEquivLabel == 0) { + unsigned EquivClass = PEClass++; + Set2PEClass[Labels] = EquivClass; + GraphNodes[NodeIndex].PointerEquivLabel = EquivClass; + Used = true; + } + } + if (!Used) + delete Labels; + } else { + SCCStack.push(NodeIndex); + } +} + +/// The technique used here is described in "Exploiting Pointer and Location +/// Equivalence to Optimize Pointer Analysis. In the 14th International Static +/// Analysis Symposium (SAS), August 2007." It is known as the "HU" algorithm, +/// and is equivalent to value numbering the collapsed constraint graph +/// including evaluating unions. +void Andersens::HU() { + DOUT << "Beginning HU\n"; + // Build a predecessor graph. This is like our constraint graph with the + // edges going in the opposite direction, and there are edges for all the + // constraints, instead of just copy constraints. We also build implicit + // edges for constraints are implied but not explicit. I.E for the constraint + // a = &b, we add implicit edges *a = b. This helps us capture more cycles + for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { + Constraint &C = Constraints[i]; + if (C.Type == Constraint::AddressOf) { + GraphNodes[C.Src].AddressTaken = true; + GraphNodes[C.Src].Direct = false; + + GraphNodes[C.Dest].PointsTo->set(C.Src); + // *Dest = src edge + unsigned RefNode = C.Dest + FirstRefNode; + if (!GraphNodes[RefNode].ImplicitPredEdges) + GraphNodes[RefNode].ImplicitPredEdges = new SparseBitVector<>; + GraphNodes[RefNode].ImplicitPredEdges->set(C.Src); + GraphNodes[C.Src].PointedToBy->set(C.Dest); + } else if (C.Type == Constraint::Load) { + if (C.Offset == 0) { + // dest = *src edge + if (!GraphNodes[C.Dest].PredEdges) + GraphNodes[C.Dest].PredEdges = new SparseBitVector<>; + GraphNodes[C.Dest].PredEdges->set(C.Src + FirstRefNode); + } else { + GraphNodes[C.Dest].Direct = false; + } + } else if (C.Type == Constraint::Store) { + if (C.Offset == 0) { + // *dest = src edge + unsigned RefNode = C.Dest + FirstRefNode; + if (!GraphNodes[RefNode].PredEdges) + GraphNodes[RefNode].PredEdges = new SparseBitVector<>; + GraphNodes[RefNode].PredEdges->set(C.Src); + } + } else { + // Dest = Src edge and *Dest = *Src edg + if (!GraphNodes[C.Dest].PredEdges) + GraphNodes[C.Dest].PredEdges = new SparseBitVector<>; + GraphNodes[C.Dest].PredEdges->set(C.Src); + unsigned RefNode = C.Dest + FirstRefNode; + if (!GraphNodes[RefNode].ImplicitPredEdges) + GraphNodes[RefNode].ImplicitPredEdges = new SparseBitVector<>; + GraphNodes[RefNode].ImplicitPredEdges->set(C.Src + FirstRefNode); + } + } + PEClass = 1; + // Do SCC finding first to condense our predecessor graph + DFSNumber = 0; + Node2DFS.insert(Node2DFS.begin(), GraphNodes.size(), 0); + Node2Deleted.insert(Node2Deleted.begin(), GraphNodes.size(), false); + Node2Visited.insert(Node2Visited.begin(), GraphNodes.size(), false); + + for (unsigned i = 0; i < FirstRefNode; ++i) { + if (FindNode(i) == i) { + unsigned Node = VSSCCRep[i]; + if (!Node2Visited[Node]) + Condense(Node); + } + } + + // Reset tables for actual labeling + Node2DFS.clear(); + Node2Visited.clear(); + Node2Deleted.clear(); + // Pre-grow our densemap so that we don't get really bad behavior + Set2PEClass.resize(GraphNodes.size()); + + // Visit the condensed graph and generate pointer equivalence labels. + Node2Visited.insert(Node2Visited.begin(), GraphNodes.size(), false); + for (unsigned i = 0; i < FirstRefNode; ++i) { + if (FindNode(i) == i) { + unsigned Node = VSSCCRep[i]; + if (!Node2Visited[Node]) + HUValNum(Node); + } + } + // PEClass nodes will be deleted by the deleting of N->PointsTo in our caller. + Set2PEClass.clear(); + DOUT << "Finished HU\n"; +} + + +/// Implementation of standard Tarjan SCC algorithm as modified by Nuutilla. +void Andersens::Condense(unsigned NodeIndex) { + unsigned MyDFS = DFSNumber++; + Node *N = &GraphNodes[NodeIndex]; + Node2Visited[NodeIndex] = true; + Node2DFS[NodeIndex] = MyDFS; + + // First process all our explicit edges + if (N->PredEdges) + for (SparseBitVector<>::iterator Iter = N->PredEdges->begin(); + Iter != N->PredEdges->end(); + ++Iter) { + unsigned j = VSSCCRep[*Iter]; + if (!Node2Deleted[j]) { + if (!Node2Visited[j]) + Condense(j); + if (Node2DFS[NodeIndex] > Node2DFS[j]) + Node2DFS[NodeIndex] = Node2DFS[j]; + } + } + + // Now process all the implicit edges + if (N->ImplicitPredEdges) + for (SparseBitVector<>::iterator Iter = N->ImplicitPredEdges->begin(); + Iter != N->ImplicitPredEdges->end(); + ++Iter) { + unsigned j = VSSCCRep[*Iter]; + if (!Node2Deleted[j]) { + if (!Node2Visited[j]) + Condense(j); + if (Node2DFS[NodeIndex] > Node2DFS[j]) + Node2DFS[NodeIndex] = Node2DFS[j]; + } + } + + // See if we found any cycles + if (MyDFS == Node2DFS[NodeIndex]) { + while (!SCCStack.empty() && Node2DFS[SCCStack.top()] >= MyDFS) { + unsigned CycleNodeIndex = SCCStack.top(); + Node *CycleNode = &GraphNodes[CycleNodeIndex]; + VSSCCRep[CycleNodeIndex] = NodeIndex; + // Unify the nodes + N->Direct &= CycleNode->Direct; + + *(N->PointsTo) |= CycleNode->PointsTo; + delete CycleNode->PointsTo; + CycleNode->PointsTo = NULL; + if (CycleNode->PredEdges) { + if (!N->PredEdges) + N->PredEdges = new SparseBitVector<>; + *(N->PredEdges) |= CycleNode->PredEdges; + delete CycleNode->PredEdges; + CycleNode->PredEdges = NULL; + } + if (CycleNode->ImplicitPredEdges) { + if (!N->ImplicitPredEdges) + N->ImplicitPredEdges = new SparseBitVector<>; + *(N->ImplicitPredEdges) |= CycleNode->ImplicitPredEdges; + delete CycleNode->ImplicitPredEdges; + CycleNode->ImplicitPredEdges = NULL; + } + SCCStack.pop(); + } + + Node2Deleted[NodeIndex] = true; + + // Set up number of incoming edges for other nodes + if (N->PredEdges) + for (SparseBitVector<>::iterator Iter = N->PredEdges->begin(); + Iter != N->PredEdges->end(); + ++Iter) + ++GraphNodes[VSSCCRep[*Iter]].NumInEdges; + } else { + SCCStack.push(NodeIndex); + } +} + +void Andersens::HUValNum(unsigned NodeIndex) { + Node *N = &GraphNodes[NodeIndex]; + Node2Visited[NodeIndex] = true; + + // Eliminate dereferences of non-pointers for those non-pointers we have + // already identified. These are ref nodes whose non-ref node: + // 1. Has already been visited determined to point to nothing (and thus, a + // dereference of it must point to nothing) + // 2. Any direct node with no predecessor edges in our graph and with no + // points-to set (since it can't point to anything either, being that it + // receives no points-to sets and has none). + if (NodeIndex >= FirstRefNode) { + unsigned j = VSSCCRep[FindNode(NodeIndex - FirstRefNode)]; + if ((Node2Visited[j] && !GraphNodes[j].PointerEquivLabel) + || (GraphNodes[j].Direct && !GraphNodes[j].PredEdges + && GraphNodes[j].PointsTo->empty())){ + return; + } + } + // Process all our explicit edges + if (N->PredEdges) + for (SparseBitVector<>::iterator Iter = N->PredEdges->begin(); + Iter != N->PredEdges->end(); + ++Iter) { + unsigned j = VSSCCRep[*Iter]; + if (!Node2Visited[j]) + HUValNum(j); + + // If this edge turned out to be the same as us, or got no pointer + // equivalence label (and thus points to nothing) , just decrement our + // incoming edges and continue. + if (j == NodeIndex || GraphNodes[j].PointerEquivLabel == 0) { + --GraphNodes[j].NumInEdges; + continue; + } + + *(N->PointsTo) |= GraphNodes[j].PointsTo; + + // If we didn't end up storing this in the hash, and we're done with all + // the edges, we don't need the points-to set anymore. + --GraphNodes[j].NumInEdges; + if (!GraphNodes[j].NumInEdges && !GraphNodes[j].StoredInHash) { + delete GraphNodes[j].PointsTo; + GraphNodes[j].PointsTo = NULL; + } + } + // If this isn't a direct node, generate a fresh variable. + if (!N->Direct) { + N->PointsTo->set(FirstRefNode + NodeIndex); + } + + // See If we have something equivalent to us, if not, generate a new + // equivalence class. + if (N->PointsTo->empty()) { + delete N->PointsTo; + N->PointsTo = NULL; + } else { + if (N->Direct) { + N->PointerEquivLabel = Set2PEClass[N->PointsTo]; + if (N->PointerEquivLabel == 0) { + unsigned EquivClass = PEClass++; + N->StoredInHash = true; + Set2PEClass[N->PointsTo] = EquivClass; + N->PointerEquivLabel = EquivClass; + } + } else { + N->PointerEquivLabel = PEClass++; + } + } +} + +/// Rewrite our list of constraints so that pointer equivalent nodes are +/// replaced by their the pointer equivalence class representative. +void Andersens::RewriteConstraints() { + std::vector NewConstraints; + + PEClass2Node.clear(); + PENLEClass2Node.clear(); + + // We may have from 1 to Graphnodes + 1 equivalence classes. + PEClass2Node.insert(PEClass2Node.begin(), GraphNodes.size() + 1, -1); + PENLEClass2Node.insert(PENLEClass2Node.begin(), GraphNodes.size() + 1, -1); + + // Rewrite constraints, ignoring non-pointer constraints, uniting equivalent + // nodes, and rewriting constraints to use the representative nodes. + for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { + Constraint &C = Constraints[i]; + unsigned RHSNode = FindNode(C.Src); + unsigned LHSNode = FindNode(C.Dest); + unsigned RHSLabel = GraphNodes[VSSCCRep[RHSNode]].PointerEquivLabel; + unsigned LHSLabel = GraphNodes[VSSCCRep[LHSNode]].PointerEquivLabel; + + // First we try to eliminate constraints for things we can prove don't point + // to anything. + if (LHSLabel == 0) { + DEBUG(PrintNode(&GraphNodes[LHSNode])); + DOUT << " is a non-pointer, ignoring constraint.\n"; + continue; + } + if (RHSLabel == 0) { + DEBUG(PrintNode(&GraphNodes[RHSNode])); + DOUT << " is a non-pointer, ignoring constraint.\n"; + continue; + } + // This constraint may be useless, and it may become useless as we translate + // it. + if (C.Src == C.Dest && C.Type == Constraint::Copy) + continue; + + C.Src = FindEquivalentNode(RHSNode, RHSLabel); + C.Dest = FindEquivalentNode(FindNode(LHSNode), LHSLabel); + if (C.Src == C.Dest && C.Type == Constraint::Copy) + continue; + + NewConstraints.push_back(C); + } + Constraints.swap(NewConstraints); + PEClass2Node.clear(); +} + +/// See if we have a node that is pointer equivalent to the one being asked +/// about, and if so, unite them and return the equivalent node. Otherwise, +/// return the original node. +unsigned Andersens::FindEquivalentNode(unsigned NodeIndex, + unsigned NodeLabel) { + if (!GraphNodes[NodeIndex].AddressTaken) { + if (PEClass2Node[NodeLabel] != -1) { + // We found an existing node with the same pointer label, so unify them. + return UniteNodes(PEClass2Node[NodeLabel], NodeIndex); + } else { + PEClass2Node[NodeLabel] = NodeIndex; + PENLEClass2Node[NodeLabel] = NodeIndex; + } + } else if (PENLEClass2Node[NodeLabel] == -1) { + PENLEClass2Node[NodeLabel] = NodeIndex; + } + + return NodeIndex; +} + +void Andersens::PrintLabels() { + for (unsigned i = 0; i < GraphNodes.size(); ++i) { + if (i < FirstRefNode) { + PrintNode(&GraphNodes[i]); + } else if (i < FirstAdrNode) { + DOUT << "REF("; + PrintNode(&GraphNodes[i-FirstRefNode]); + DOUT <<")"; + } else { + DOUT << "ADR("; + PrintNode(&GraphNodes[i-FirstAdrNode]); + DOUT <<")"; + } + + DOUT << " has pointer label " << GraphNodes[i].PointerEquivLabel + << " and SCC rep " << VSSCCRep[i] + << " and is " << (GraphNodes[i].Direct ? "Direct" : "Not direct") + << "\n"; + } +} + +/// Optimize the constraints by performing offline variable substitution and +/// other optimizations. +void Andersens::OptimizeConstraints() { + DOUT << "Beginning constraint optimization\n"; + + // Function related nodes need to stay in the same relative position and can't + // be location equivalent. + for (std::map::iterator Iter = MaxK.begin(); + Iter != MaxK.end(); + ++Iter) { + for (unsigned i = Iter->first; + i != Iter->first + Iter->second; + ++i) { + GraphNodes[i].AddressTaken = true; + GraphNodes[i].Direct = false; + } + } + + ClumpAddressTaken(); + FirstRefNode = GraphNodes.size(); + FirstAdrNode = FirstRefNode + GraphNodes.size(); + GraphNodes.insert(GraphNodes.end(), 2 * GraphNodes.size(), + Node(false)); + VSSCCRep.resize(GraphNodes.size()); + for (unsigned i = 0; i < GraphNodes.size(); ++i) { + VSSCCRep[i] = i; + } + HVN(); + for (unsigned i = 0; i < GraphNodes.size(); ++i) { + Node *N = &GraphNodes[i]; + delete N->PredEdges; + N->PredEdges = NULL; + delete N->ImplicitPredEdges; + N->ImplicitPredEdges = NULL; + } +#undef DEBUG_TYPE +#define DEBUG_TYPE "anders-aa-labels" + DEBUG(PrintLabels()); +#undef DEBUG_TYPE +#define DEBUG_TYPE "anders-aa" + RewriteConstraints(); + // Delete the adr nodes. + GraphNodes.resize(FirstRefNode * 2); + + // Now perform HU + for (unsigned i = 0; i < GraphNodes.size(); ++i) { + Node *N = &GraphNodes[i]; + if (FindNode(i) == i) { + N->PointsTo = new SparseBitVector<>; + N->PointedToBy = new SparseBitVector<>; + // Reset our labels + } + VSSCCRep[i] = i; + N->PointerEquivLabel = 0; + } + HU(); +#undef DEBUG_TYPE +#define DEBUG_TYPE "anders-aa-labels" + DEBUG(PrintLabels()); +#undef DEBUG_TYPE +#define DEBUG_TYPE "anders-aa" + RewriteConstraints(); + for (unsigned i = 0; i < GraphNodes.size(); ++i) { + if (FindNode(i) == i) { + Node *N = &GraphNodes[i]; + delete N->PointsTo; + delete N->PredEdges; + delete N->ImplicitPredEdges; + delete N->PointedToBy; + } + } + GraphNodes.erase(GraphNodes.begin() + FirstRefNode, GraphNodes.end()); + DOUT << "Finished constraint optimization\n"; + FirstRefNode = 0; + FirstAdrNode = 0; +} + +/// Unite pointer but not location equivalent variables, now that the constraint +/// graph is built. +void Andersens::UnitePointerEquivalences() { + DOUT << "Uniting remaining pointer equivalences\n"; + for (unsigned i = 0; i < GraphNodes.size(); ++i) { + if (GraphNodes[i].AddressTaken && GraphNodes[i].NodeRep == SelfRep) { + unsigned Label = GraphNodes[i].PointerEquivLabel; + + if (Label && PENLEClass2Node[Label] != -1) + UniteNodes(i, PENLEClass2Node[Label]); + } + } + DOUT << "Finished remaining pointer equivalences\n"; + PENLEClass2Node.clear(); +} + +/// Create the constraint graph used for solving points-to analysis. +/// void Andersens::CreateConstraintGraph() { for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { Constraint &C = Constraints[i]; @@ -1181,8 +2003,13 @@ bool Changed = true; unsigned Iteration = 0; - // We create the bitmaps here to avoid getting jerked around by the compiler - // creating objects behind our back and wasting lots of memory. + OptimizeConstraints(); +#undef DEBUG_TYPE +#define DEBUG_TYPE "anders-aa-constraints" + DEBUG(PrintConstraints()); +#undef DEBUG_TYPE +#define DEBUG_TYPE "anders-aa" + for (unsigned i = 0; i < GraphNodes.size(); ++i) { Node *N = &GraphNodes[i]; N->PointsTo = new SparseBitVector<>; @@ -1190,9 +2017,12 @@ N->Edges = new SparseBitVector<>; } CreateConstraintGraph(); - + UnitePointerEquivalences(); + assert(SCCStack.empty() && "SCC Stack should be empty by now!"); Topo2Node.insert(Topo2Node.begin(), GraphNodes.size(), Unvisited); Node2Topo.insert(Node2Topo.begin(), GraphNodes.size(), Unvisited); + Node2DFS.clear(); + Node2Deleted.clear(); Node2DFS.insert(Node2DFS.begin(), GraphNodes.size(), 0); Node2Deleted.insert(Node2Deleted.begin(), GraphNodes.size(), false); DFSNumber = 0; @@ -1214,7 +2044,7 @@ do { Changed = false; ++NumIters; - DOUT << "Starting iteration #" << Iteration++; + DOUT << "Starting iteration #" << Iteration++ << "\n"; // TODO: In the microoptimization category, we could just make Topo2Node // a fast map and thus only contain the visited nodes. for (unsigned i = 0; i < GraphNodes.size(); ++i) { @@ -1248,7 +2078,7 @@ // TODO: We could delete redundant constraints here. // Src and Dest will be the vars we are going to process. // This may look a bit ugly, but what it does is allow us to process - // both store and load constraints with the same function. + // both store and load constraints with the same code. // Load constraints say that every member of our RHS solution has K // added to it, and that variable gets an edge to LHS. We also union // RHS+K's solution into the LHS solution. @@ -1282,11 +2112,10 @@ CurrMember = *bi; // Need to increment the member by K since that is where we are - // supposed to copy to/from - // Node that in positive weight cycles, which occur in address taking - // of fields, K can go past - // MaxK[CurrMember] elements, even though that is all it could - // point to. + // supposed to copy to/from. Note that in positive weight cycles, + // which occur in address taking of fields, K can go past + // MaxK[CurrMember] elements, even though that is all it could point + // to. if (K > 0 && K > MaxK[CurrMember]) continue; else @@ -1393,12 +2222,17 @@ SecondNode->NodeRep = First; FirstNode->Changed |= SecondNode->Changed; - FirstNode->PointsTo |= *(SecondNode->PointsTo); - FirstNode->Edges |= *(SecondNode->Edges); - FirstNode->Constraints.splice(FirstNode->Constraints.begin(), - SecondNode->Constraints); - delete FirstNode->OldPointsTo; - FirstNode->OldPointsTo = new SparseBitVector<>; + if (FirstNode->PointsTo && SecondNode->PointsTo) + FirstNode->PointsTo |= *(SecondNode->PointsTo); + if (FirstNode->Edges && SecondNode->Edges) + FirstNode->Edges |= *(SecondNode->Edges); + if (!FirstNode->Constraints.empty() && !SecondNode->Constraints.empty()) + FirstNode->Constraints.splice(FirstNode->Constraints.begin(), + SecondNode->Constraints); + if (FirstNode->OldPointsTo) { + delete FirstNode->OldPointsTo; + FirstNode->OldPointsTo = new SparseBitVector<>; + } // Destroy interesting parts of the merged-from node. delete SecondNode->OldPointsTo; @@ -1479,35 +2313,36 @@ if (N == &GraphNodes[getObject(V)]) cerr << ""; } +void Andersens::PrintConstraint(const Constraint &C) { + if (C.Type == Constraint::Store) { + cerr << "*"; + if (C.Offset != 0) + cerr << "("; + } + PrintNode(&GraphNodes[C.Dest]); + if (C.Type == Constraint::Store && C.Offset != 0) + cerr << " + " << C.Offset << ")"; + cerr << " = "; + if (C.Type == Constraint::Load) { + cerr << "*"; + if (C.Offset != 0) + cerr << "("; + } + else if (C.Type == Constraint::AddressOf) + cerr << "&"; + PrintNode(&GraphNodes[C.Src]); + if (C.Offset != 0 && C.Type != Constraint::Store) + cerr << " + " << C.Offset; + if (C.Type == Constraint::Load && C.Offset != 0) + cerr << ")"; + cerr << "\n"; +} void Andersens::PrintConstraints() { cerr << "Constraints:\n"; - for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { - const Constraint &C = Constraints[i]; - if (C.Type == Constraint::Store) { - cerr << "*"; - if (C.Offset != 0) - cerr << "("; - } - PrintNode(&GraphNodes[C.Dest]); - if (C.Type == Constraint::Store && C.Offset != 0) - cerr << " + " << C.Offset << ")"; - cerr << " = "; - if (C.Type == Constraint::Load) { - cerr << "*"; - if (C.Offset != 0) - cerr << "("; - } - else if (C.Type == Constraint::AddressOf) - cerr << "&"; - PrintNode(&GraphNodes[C.Src]); - if (C.Offset != 0 && C.Type != Constraint::Store) - cerr << " + " << C.Offset; - if (C.Type == Constraint::Load && C.Offset != 0) - cerr << ")"; - cerr << "\n"; - } + for (unsigned i = 0, e = Constraints.size(); i != e; ++i) + PrintConstraint(Constraints[i]); } void Andersens::PrintPointsToGraph() { From dpatel at apple.com Mon Sep 24 13:02:42 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 24 Sep 2007 20:02:42 -0000 Subject: [llvm-commits] [llvm] r42270 - in /llvm/trunk: lib/Transforms/Scalar/LICM.cpp test/Transforms/LICM/2007-09-24-PromoteNullValue.ll Message-ID: <200709242002.l8OK2ggR030293@zion.cs.uiuc.edu> Author: dpatel Date: Mon Sep 24 15:02:42 2007 New Revision: 42270 URL: http://llvm.org/viewvc/llvm-project?rev=42270&view=rev Log: Do not promote null values because it may be unsafe to do so. Added: llvm/trunk/test/Transforms/LICM/2007-09-24-PromoteNullValue.ll Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=42270&r1=42269&r2=42270&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Mon Sep 24 15:02:42 2007 @@ -800,6 +800,10 @@ break; } + // Do not promote null values because it may be unsafe to do so. + if (isa(V)) + PointerOk = false; + if (GetElementPtrInst *GEP = dyn_cast(V)) { // If GEP base is NULL then the calculated address used by Store or // Load instruction is invalid. Do not promote this value because Added: llvm/trunk/test/Transforms/LICM/2007-09-24-PromoteNullValue.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/2007-09-24-PromoteNullValue.ll?rev=42270&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LICM/2007-09-24-PromoteNullValue.ll (added) +++ llvm/trunk/test/Transforms/LICM/2007-09-24-PromoteNullValue.ll Mon Sep 24 15:02:42 2007 @@ -0,0 +1,46 @@ +; Do not promote null value because it may be unsafe to do so. +; RUN: llvm-as < %s | opt -licm | llvm-dis | not grep promoted + +define i32 @f(i32 %foo, i32 %bar, i32 %com) { +entry: + %tmp2 = icmp eq i32 %foo, 0 ; [#uses=1] + br i1 %tmp2, label %cond_next, label %cond_true + +cond_true: ; preds = %entry + br label %return + +cond_next: ; preds = %entry + br label %bb + +bb: ; preds = %bb15, %cond_next + switch i32 %bar, label %bb15 [ + i32 1, label %bb6 + ] + +bb6: ; preds = %bb + %tmp8 = icmp eq i32 %com, 0 ; [#uses=1] + br i1 %tmp8, label %cond_next14, label %cond_true11 + +cond_true11: ; preds = %bb6 + br label %return + +cond_next14: ; preds = %bb6 + store i8 0, i8* null + br label %bb15 + +bb15: ; preds = %cond_next14, %bb + br label %bb + +return: ; preds = %cond_true11, %cond_true + %storemerge = phi i32 [ 0, %cond_true ], [ undef, %cond_true11 ] ; [#uses=1] + ret i32 %storemerge +} + +define i32 @kdMain() { +entry: + %tmp1 = call i32 @f( i32 0, i32 1, i32 1 ) ; [#uses=0] + call void @exit( i32 0 ) + unreachable +} + +declare void @exit(i32) From baldrick at free.fr Mon Sep 24 13:08:42 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 24 Sep 2007 22:08:42 +0200 Subject: [llvm-commits] [llvm] r42269 - in /llvm/trunk: include/llvm/ADT/DenseMap.h include/llvm/ADT/SparseBitVector.h lib/Analysis/IPA/Andersens.cpp In-Reply-To: <200709241945.l8OJjo1M029802@zion.cs.uiuc.edu> References: <200709241945.l8OJjo1M029802@zion.cs.uiuc.edu> Message-ID: <200709242208.46621.baldrick@free.fr> Hi DannyB, > @@ -287,6 +286,14 @@ > } > BecameZero = allzero; > } > + // Get a hash value for this element; > + uint64_t getHashValue() const { shouldn't there be a blank line before the added lines? > +// The Offline constraint graph optimization portion includes offline variable The Offline -> The offline > +// substitution algorithms intended to pointer and location equivalences. Does not parse! > + // graph. Due to various optimizations, not always the case that there is a not always the case -> it is not always the case > + // True if our ponits-to set is in the Set2PEClass map ponits-to -> points-to > + // True if our node has no indirect constraints (Complex or otherwise) Complex -> complex > + // their arg nodes, which must be kept at the same position relative to > + // their base function node. > + // kept at the same position relative to their base function node. Looks like this last line shouldn't be there. Ciao, Duncan. From bruno.cardoso at gmail.com Mon Sep 24 13:15:11 2007 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Mon, 24 Sep 2007 20:15:11 -0000 Subject: [llvm-commits] [llvm] r42271 - in /llvm/trunk/lib/Target/Mips: MipsAsmPrinter.cpp MipsISelDAGToDAG.cpp MipsInstrInfo.td Message-ID: <200709242015.l8OKFBRF030624@zion.cs.uiuc.edu> Author: bruno Date: Mon Sep 24 15:15:11 2007 New Revision: 42271 URL: http://llvm.org/viewvc/llvm-project?rev=42271&view=rev Log: Added "LoadEffective" pattern to handle stack locations. Fixed some comments Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=42271&r1=42270&r2=42271&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Mon Sep 24 15:15:11 2007 @@ -141,7 +141,7 @@ #endif unsigned int Bitmask = getSavedRegsBitmask(false, MF); - O << "\t.mask\t"; + O << "\t.mask \t"; printHex32(Bitmask); O << "," << Offset << "\n"; } @@ -366,9 +366,16 @@ void MipsAsmPrinter:: printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier) { - // lw/sw $reg, MemOperand - // will turn into : - // lw/sw $reg, imm($reg) + // when using stack locations for not load/store instructions + // print the same way as all normal 3 operand instructions. + if (Modifier && !strcmp(Modifier, "stackloc")) { + printOperand(MI, opNum+1); + O << ", "; + printOperand(MI, opNum); + return; + } + + // Load/Store memory operands -- imm($reg) printOperand(MI, opNum); O << "("; printOperand(MI, opNum+1); Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp?rev=42271&r1=42270&r2=42271&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Mon Sep 24 15:15:11 2007 @@ -196,8 +196,8 @@ } /// - // Instruction Selection not handled by custom or by the - // auto-generated tablegen selection should be handled here + // Instruction Selection not handled by the auto-generated + // tablegen selection should be handled here. /// switch(Opcode) { Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=42271&r1=42270&r2=42271&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Mon Sep 24 15:15:11 2007 @@ -332,6 +332,12 @@ !strconcat(instr_asm, " $dst, $src"), [], IIAlu>; +class EffectiveAddress : + FI<0x09, + (outs CPURegs:$dst), + (ins mem:$addr), + instr_asm, + [(set CPURegs:$dst, addr:$addr)], IIAlu>; //===----------------------------------------------------------------------===// // Pseudo instructions @@ -468,6 +474,12 @@ "jr $target", [(MipsRet CPURegs:$target)], IIBranch>; } +// FrameIndexes are legalized when they are operands from load/store +// instructions. The same not happens for stack address copies, so an +// add op with mem ComplexPattern is used and the stack address copy +// can be matched. It's similar to Sparc LEA_ADDRi +def LEA_ADDiu : EffectiveAddress<"addiu $dst, ${addr:stackloc}">; + //===----------------------------------------------------------------------===// // Arbitrary patterns that map to one or more instructions //===----------------------------------------------------------------------===// From djg at cray.com Mon Sep 24 13:36:14 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 24 Sep 2007 15:36:14 -0500 Subject: [llvm-commits] [llvm] r42270 - in /llvm/trunk: lib/Transforms/Scalar/LICM.cpp test/Transforms/LICM/2007-09-24-PromoteNullValue.ll Message-ID: <20070924203614.GV21991@village.us.cray.com> > Do not promote null values because it may be unsafe to do so. Interesting. See our earlier discussion on LICM checking for NULL constants :-}. Dan -- Dan Gohman, Cray Inc. From djg at cray.com Mon Sep 24 13:58:13 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 24 Sep 2007 20:58:13 -0000 Subject: [llvm-commits] [llvm] r42272 - in /llvm/trunk: include/llvm/CodeGen/AsmPrinter.h lib/CodeGen/AsmPrinter.cpp Message-ID: <200709242058.l8OKwE82032030@zion.cs.uiuc.edu> Author: djg Date: Mon Sep 24 15:58:13 2007 New Revision: 42272 URL: http://llvm.org/viewvc/llvm-project?rev=42272&view=rev Log: Add a routine for emitting .file directives, for setting up file numbers to use with .loc directives. Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h llvm/trunk/lib/CodeGen/AsmPrinter.cpp Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AsmPrinter.h?rev=42272&r1=42271&r2=42272&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original) +++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Mon Sep 24 15:58:13 2007 @@ -248,6 +248,9 @@ /// @verbatim (Eg. '\t') @endverbatim void EmitString(const std::string &String) const; + /// EmitFile - Emit a .file directive. + void EmitFile(unsigned Number, const std::string &Name) const; + //===------------------------------------------------------------------===// /// EmitAlignment - Emit an alignment directive to the specified power of Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter.cpp?rev=42272&r1=42271&r2=42272&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Mon Sep 24 15:58:13 2007 @@ -618,6 +618,17 @@ } +/// EmitFile - Emit a .file directive. +void AsmPrinter::EmitFile(unsigned Number, const std::string &Name) const { + O << "\t.file\t" << Number << " \""; + for (unsigned i = 0, N = Name.size(); i < N; ++i) { + unsigned char C = Name[i]; + printStringChar(O, C); + } + O << "\""; +} + + //===----------------------------------------------------------------------===// // EmitAlignment - Emit an alignment directive to the specified power of From dalej at apple.com Mon Sep 24 14:06:09 2007 From: dalej at apple.com (Dale Johannesen) Date: Mon, 24 Sep 2007 21:06:09 -0000 Subject: [llvm-commits] [llvm] r42273 - /llvm/trunk/lib/VMCore/ConstantFold.cpp Message-ID: <200709242106.l8OL69dw032227@zion.cs.uiuc.edu> Author: johannes Date: Mon Sep 24 16:06:09 2007 New Revision: 42273 URL: http://llvm.org/viewvc/llvm-project?rev=42273&view=rev Log: float->int conversion rounds toward 0. Duh. Fixes PR1698. Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=42273&r1=42272&r2=42273&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ConstantFold.cpp (original) +++ llvm/trunk/lib/VMCore/ConstantFold.cpp Mon Sep 24 16:06:09 2007 @@ -196,7 +196,7 @@ uint32_t DestBitWidth = cast(DestTy)->getBitWidth(); APFloat::opStatus status = V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI, - APFloat::rmNearestTiesToEven); + APFloat::rmTowardZero); if (status!=APFloat::opOK && status!=APFloat::opInexact) return 0; // give up APInt Val(DestBitWidth, 2, x); From djg at cray.com Mon Sep 24 14:09:53 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 24 Sep 2007 21:09:53 -0000 Subject: [llvm-commits] [llvm] r42274 - in /llvm/trunk: include/llvm/Target/TargetAsmInfo.h lib/Target/TargetAsmInfo.cpp Message-ID: <200709242109.l8OL9snq032326@zion.cs.uiuc.edu> Author: djg Date: Mon Sep 24 16:09:53 2007 New Revision: 42274 URL: http://llvm.org/viewvc/llvm-project?rev=42274&view=rev Log: Merge hasDotLoc and hasDotFile into hasDotLocAndDotFile since .loc and .file aren't really usable without each other. Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h llvm/trunk/lib/Target/TargetAsmInfo.cpp Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmInfo.h?rev=42274&r1=42273&r2=42274&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetAsmInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetAsmInfo.h Mon Sep 24 16:09:53 2007 @@ -286,14 +286,11 @@ /// bool HasLEB128; // Defaults to false. - /// hasDotLoc - True if target asm supports .loc directives. + /// hasDotLocAndDotFile - True if target asm supports .loc and .file + /// directives for emitting debugging information. /// - bool HasDotLoc; // Defaults to false. + bool HasDotLocAndDotFile; // Defaults to false. - /// HasDotFile - True if target asm supports .file directives. - /// - bool HasDotFile; // Defaults to false. - /// SupportsDebugInformation - True if target supports emission of debugging /// information. bool SupportsDebugInformation; @@ -568,11 +565,8 @@ bool hasLEB128() const { return HasLEB128; } - bool hasDotLoc() const { - return HasDotLoc; - } - bool hasDotFile() const { - return HasDotFile; + bool hasDotLocAndDotFile() const { + return HasDotLocAndDotFile; } bool doesSupportDebugInformation() const { return SupportsDebugInformation; Modified: llvm/trunk/lib/Target/TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetAsmInfo.cpp?rev=42274&r1=42273&r2=42274&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/TargetAsmInfo.cpp Mon Sep 24 16:09:53 2007 @@ -81,8 +81,7 @@ AbsoluteDebugSectionOffsets(false), AbsoluteEHSectionOffsets(false), HasLEB128(false), - HasDotLoc(false), - HasDotFile(false), + HasDotLocAndDotFile(false), SupportsDebugInformation(false), SupportsExceptionHandling(false), DwarfRequiresFrameSection(true), From djg at cray.com Mon Sep 24 14:32:19 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 24 Sep 2007 21:32:19 -0000 Subject: [llvm-commits] [llvm] r42275 - /llvm/trunk/lib/CodeGen/DwarfWriter.cpp Message-ID: <200709242132.l8OLWK1u000420@zion.cs.uiuc.edu> Author: djg Date: Mon Sep 24 16:32:18 2007 New Revision: 42275 URL: http://llvm.org/viewvc/llvm-project?rev=42275&view=rev Log: Add support for emitting .file directives to set up file numbers for use with .loc directives. Modified: llvm/trunk/lib/CodeGen/DwarfWriter.cpp Modified: llvm/trunk/lib/CodeGen/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DwarfWriter.cpp?rev=42275&r1=42274&r2=42275&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/DwarfWriter.cpp Mon Sep 24 16:32:18 2007 @@ -28,6 +28,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/Mangler.h" +#include "llvm/System/Path.h" #include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/MRegisterInfo.h" #include "llvm/Target/TargetData.h" @@ -1967,6 +1968,19 @@ if (didInitial) return; didInitial = true; + // Print out .file directives to specify files for .loc directives. + if (TAI->hasDotLocAndDotFile()) { + const UniqueVector &SourceFiles = MMI->getSourceFiles(); + const UniqueVector &Directories = MMI->getDirectories(); + for (unsigned i = 1, e = SourceFiles.size(); i <= e; ++i) { + sys::Path FullPath(Directories[SourceFiles[i].getDirectoryID()]); + bool AppendOk = FullPath.appendComponent(SourceFiles[i].getName()); + assert(AppendOk && "Could not append filename to directory!"); + Asm->EmitFile(i, FullPath.toString()); + Asm->EOL(); + } + } + // Dwarf sections base addresses. if (TAI->doesDwarfRequireFrameSection()) { Asm->SwitchToDataSection(TAI->getDwarfFrameSection()); From djg at cray.com Mon Sep 24 14:36:21 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 24 Sep 2007 21:36:21 -0000 Subject: [llvm-commits] [llvm] r42276 - /llvm/trunk/lib/CodeGen/DwarfWriter.cpp Message-ID: <200709242136.l8OLaMwe000514@zion.cs.uiuc.edu> Author: djg Date: Mon Sep 24 16:36:21 2007 New Revision: 42276 URL: http://llvm.org/viewvc/llvm-project?rev=42276&view=rev Log: Move the Asm->EOL() call for EmitDebugARanges outside the #ifdef for consistency with the other currently empty sections. Modified: llvm/trunk/lib/CodeGen/DwarfWriter.cpp Modified: llvm/trunk/lib/CodeGen/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DwarfWriter.cpp?rev=42276&r1=42275&r2=42276&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/DwarfWriter.cpp Mon Sep 24 16:36:21 2007 @@ -2525,9 +2525,9 @@ Asm->EmitInt32(0); Asm->EOL("EOM (1)"); Asm->EmitInt32(0); Asm->EOL("EOM (2)"); + #endif Asm->EOL(); - #endif } /// EmitDebugRanges - Emit visible names into a debug ranges section. From djg at cray.com Mon Sep 24 14:43:52 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 24 Sep 2007 21:43:52 -0000 Subject: [llvm-commits] [llvm] r42277 - /llvm/trunk/lib/CodeGen/DwarfWriter.cpp Message-ID: <200709242143.l8OLhqCU000698@zion.cs.uiuc.edu> Author: djg Date: Mon Sep 24 16:43:52 2007 New Revision: 42277 URL: http://llvm.org/viewvc/llvm-project?rev=42277&view=rev Log: Don't emit .debug_line header data if there aren't any lines to put in it, such as will happen when .loc directives are used. Modified: llvm/trunk/lib/CodeGen/DwarfWriter.cpp Modified: llvm/trunk/lib/CodeGen/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DwarfWriter.cpp?rev=42277&r1=42276&r2=42277&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/DwarfWriter.cpp Mon Sep 24 16:43:52 2007 @@ -2196,6 +2196,11 @@ /// EmitDebugLines - Emit source line information. /// void EmitDebugLines() { + // If there are no lines to emit (such as when we're using .loc directives + // to emit .debug_line information) don't emit a .debug_line header. + if (SectionSourceLines.empty()) + return; + // Minimum line delta, thus ranging from -10..(255-10). const int MinLineDelta = -(DW_LNS_fixed_advance_pc + 1); // Maximum line delta, thus ranging from -10..(255-10). From djg at cray.com Mon Sep 24 14:54:15 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 24 Sep 2007 21:54:15 -0000 Subject: [llvm-commits] [llvm] r42278 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200709242154.l8OLsF56000956@zion.cs.uiuc.edu> Author: djg Date: Mon Sep 24 16:54:14 2007 New Revision: 42278 URL: http://llvm.org/viewvc/llvm-project?rev=42278&view=rev Log: Add support on x86 for having Legalize lower ISD::LOCATION to ISD::DEBUG_LOC instead of ISD::LABEL with a manual .debug_line entry when the assembler supports .file and .loc directives. 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=42278&r1=42277&r2=42278&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Sep 24 16:54:14 2007 @@ -32,6 +32,7 @@ #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetOptions.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ParameterAttributes.h" @@ -229,9 +230,13 @@ setOperationAction(ISD::MEMSET , MVT::Other, Custom); setOperationAction(ISD::MEMCPY , MVT::Other, Custom); - // We don't have line number support yet. + // Use the default ISD::LOCATION expansion, and tell Legalize it's + // ok to use DEBUG_LOC if we have an assembler that supports it. setOperationAction(ISD::LOCATION, MVT::Other, Expand); - setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); + if (TM.getTargetAsmInfo()->hasDotLocAndDotFile()) + setOperationAction(ISD::DEBUG_LOC, MVT::Other, Legal); + else + setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); // FIXME - use subtarget debug flags if (!Subtarget->isTargetDarwin() && !Subtarget->isTargetELF() && From dberlin at dberlin.org Mon Sep 24 15:20:43 2007 From: dberlin at dberlin.org (Daniel Berlin) Date: Mon, 24 Sep 2007 18:20:43 -0400 Subject: [llvm-commits] [llvm] r42269 - in /llvm/trunk: include/llvm/ADT/DenseMap.h include/llvm/ADT/SparseBitVector.h lib/Analysis/IPA/Andersens.cpp In-Reply-To: <200709242208.46621.baldrick@free.fr> References: <200709241945.l8OJjo1M029802@zion.cs.uiuc.edu> <200709242208.46621.baldrick@free.fr> Message-ID: <4aca3dc20709241520g21478a4bn83802c5d35c03cc5@mail.gmail.com> On 9/24/07, Duncan Sands wrote: > Hi DannyB, > > > @@ -287,6 +286,14 @@ > > } > > BecameZero = allzero; > > } > > + // Get a hash value for this element; > > + uint64_t getHashValue() const { > > shouldn't there be a blank line before the added lines? > > > +// The Offline constraint graph optimization portion includes offline variable > > The Offline -> The offline > > > +// substitution algorithms intended to pointer and location equivalences. > > Does not parse! > > > + // graph. Due to various optimizations, not always the case that there is a > > not always the case -> it is not always the case > > > + // True if our ponits-to set is in the Set2PEClass map > > ponits-to -> points-to > > > + // True if our node has no indirect constraints (Complex or otherwise) > > Complex -> complex > > > + // their arg nodes, which must be kept at the same position relative to > > + // their base function node. > > + // kept at the same position relative to their base function node. > > Looks like this last line shouldn't be there. All fixed > > Ciao, > > Duncan. > From dberlin at dberlin.org Mon Sep 24 15:20:45 2007 From: dberlin at dberlin.org (Daniel Berlin) Date: Mon, 24 Sep 2007 22:20:45 -0000 Subject: [llvm-commits] [llvm] r42279 - in /llvm/trunk: include/llvm/ADT/SparseBitVector.h lib/Analysis/IPA/Andersens.cpp Message-ID: <200709242220.l8OMKjYP001578@zion.cs.uiuc.edu> Author: dannyb Date: Mon Sep 24 17:20:45 2007 New Revision: 42279 URL: http://llvm.org/viewvc/llvm-project?rev=42279&view=rev Log: Comment fixups Modified: llvm/trunk/include/llvm/ADT/SparseBitVector.h llvm/trunk/lib/Analysis/IPA/Andersens.cpp Modified: llvm/trunk/include/llvm/ADT/SparseBitVector.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SparseBitVector.h?rev=42279&r1=42278&r2=42279&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/SparseBitVector.h (original) +++ llvm/trunk/include/llvm/ADT/SparseBitVector.h Mon Sep 24 17:20:45 2007 @@ -286,6 +286,7 @@ } BecameZero = allzero; } + // Get a hash value for this element; uint64_t getHashValue() const { uint64_t HashVal = 0; Modified: llvm/trunk/lib/Analysis/IPA/Andersens.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/Andersens.cpp?rev=42279&r1=42278&r2=42279&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IPA/Andersens.cpp (original) +++ llvm/trunk/lib/Analysis/IPA/Andersens.cpp Mon Sep 24 17:20:45 2007 @@ -30,11 +30,11 @@ // B can point to. Constraints can handle copies, loads, and stores, and // address taking. // -// The Offline constraint graph optimization portion includes offline variable -// substitution algorithms intended to pointer and location equivalences. -// Pointer equivalences are those pointers that will have the same points-to -// sets, and location equivalences are those variables that always appear -// together in points-to sets. +// The offline constraint graph optimization portion includes offline variable +// substitution algorithms intended to computer pointer and location +// equivalences. Pointer equivalences are those pointers that will have the +// same points-to sets, and location equivalences are those variables that +// always appear together in points-to sets. // // The inclusion constraint solving phase iteratively propagates the inclusion // constraints until a fixed point is reached. This is an O(N^3) algorithm. @@ -137,10 +137,10 @@ }; // Node class - This class is used to represent a node in the constraint - // graph. Due to various optimizations, not always the case that there is a - // mapping from a Node to a Value. In particular, we add artificial Node's - // that represent the set of pointed-to variables shared for each location - // equivalent Node. + // graph. Due to various optimizations, it is not always the case that + // there is a mapping from a Node to a Value. In particular, we add + // artificial Node's that represent the set of pointed-to variables shared + // for each location equivalent Node. struct Node { Value *Val; SparseBitVector<> *Edges; @@ -160,15 +160,14 @@ // Number of incoming edges, used during variable substitution to early // free the points-to sets unsigned NumInEdges; - // True if our ponits-to set is in the Set2PEClass map + // True if our points-to set is in the Set2PEClass map bool StoredInHash; - // True if our node has no indirect constraints (Complex or otherwise) + // True if our node has no indirect constraints (complex or otherwise) bool Direct; // True if the node is address taken, *or* it is part of a group of nodes // that must be kept together. This is set to true for functions and // their arg nodes, which must be kept at the same position relative to // their base function node. - // kept at the same position relative to their base function node. bool AddressTaken; // Nodes in cycles (or in equivalence classes) are united together using a From isanbard at gmail.com Mon Sep 24 15:43:49 2007 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 24 Sep 2007 22:43:49 -0000 Subject: [llvm-commits] [llvm] r42280 - /llvm/trunk/lib/Analysis/IPA/Andersens.cpp Message-ID: <200709242243.l8OMhnDu002217@zion.cs.uiuc.edu> Author: void Date: Mon Sep 24 17:43:48 2007 New Revision: 42280 URL: http://llvm.org/viewvc/llvm-project?rev=42280&view=rev Log: Don't execute dump unless NDEBUG isn't defined. Modified: llvm/trunk/lib/Analysis/IPA/Andersens.cpp Modified: llvm/trunk/lib/Analysis/IPA/Andersens.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/Andersens.cpp?rev=42280&r1=42279&r2=42280&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IPA/Andersens.cpp (original) +++ llvm/trunk/lib/Analysis/IPA/Andersens.cpp Mon Sep 24 17:43:48 2007 @@ -1185,7 +1185,9 @@ } void dumpToDOUT(SparseBitVector<> *bitmap) { +#ifndef NDEBUG dump(*bitmap, DOUT); +#endif } From dalej at apple.com Mon Sep 24 15:52:39 2007 From: dalej at apple.com (Dale Johannesen) Date: Mon, 24 Sep 2007 22:52:39 -0000 Subject: [llvm-commits] [llvm] r42281 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200709242252.l8OMqdq3002464@zion.cs.uiuc.edu> Author: johannes Date: Mon Sep 24 17:52:39 2007 New Revision: 42281 URL: http://llvm.org/viewvc/llvm-project?rev=42281&view=rev Log: When mixing SSE and x87 codegen, it's possible to have situations where an SSE instruction turns into multiple blocks, with the live range of an x87 register crossing them. To do this correctly make sure we examine all blocks when inserting FP_REG_KILL. PR 1697. (This was exposed by my fix for PR 1681, but the same thing could happen mixing x87 long double with SSE.) 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=42281&r1=42280&r2=42281&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Mon Sep 24 17:52:39 2007 @@ -482,14 +482,17 @@ // block defines any FP values. If so, put an FP_REG_KILL instruction before // the terminator of the block. - // Note that FP stack instructions *are* used in SSE code for long double, - // so we do need this check. - bool ContainsFPCode = false; + // Note that FP stack instructions are used in all modes for long double, + // so we always need to do this check. + // Also note that it's possible for an FP stack register to be live across + // an instruction that produces multiple basic blocks (SSE CMOV) so we + // must check all the generated basic blocks. // Scan all of the machine instructions in these MBBs, checking for FP // stores. (RFP32 and RFP64 will not exist in SSE mode, but RFP80 might.) MachineFunction::iterator MBBI = FirstMBB; do { + bool ContainsFPCode = false; for (MachineBasicBlock::iterator I = MBBI->begin(), E = MBBI->end(); !ContainsFPCode && I != E; ++I) { if (I->getNumOperands() != 0 && I->getOperand(0).isRegister()) { @@ -507,35 +510,34 @@ } } } - } while (!ContainsFPCode && &*(MBBI++) != BB); - - // Check PHI nodes in successor blocks. These PHI's will be lowered to have - // a copy of the input value in this block. In SSE mode, we only care about - // 80-bit values. - if (!ContainsFPCode) { - // Final check, check LLVM BB's that are successors to the LLVM BB - // corresponding to BB for FP PHI nodes. - const BasicBlock *LLVMBB = BB->getBasicBlock(); - const PHINode *PN; - for (succ_const_iterator SI = succ_begin(LLVMBB), E = succ_end(LLVMBB); - !ContainsFPCode && SI != E; ++SI) { - for (BasicBlock::const_iterator II = SI->begin(); - (PN = dyn_cast(II)); ++II) { - if (PN->getType()==Type::X86_FP80Ty || - (!Subtarget->hasSSE2() && PN->getType()->isFloatingPoint())) { - ContainsFPCode = true; - break; + // Check PHI nodes in successor blocks. These PHI's will be lowered to have + // a copy of the input value in this block. In SSE mode, we only care about + // 80-bit values. + if (!ContainsFPCode) { + // Final check, check LLVM BB's that are successors to the LLVM BB + // corresponding to BB for FP PHI nodes. + const BasicBlock *LLVMBB = BB->getBasicBlock(); + const PHINode *PN; + for (succ_const_iterator SI = succ_begin(LLVMBB), E = succ_end(LLVMBB); + !ContainsFPCode && SI != E; ++SI) { + for (BasicBlock::const_iterator II = SI->begin(); + (PN = dyn_cast(II)); ++II) { + if (PN->getType()==Type::X86_FP80Ty || + (!Subtarget->hasSSE1() && PN->getType()->isFloatingPoint()) || + (!Subtarget->hasSSE2() && PN->getType()==Type::DoubleTy)) { + ContainsFPCode = true; + break; + } } } } - } - - // Finally, if we found any FP code, emit the FP_REG_KILL instruction. - if (ContainsFPCode) { - BuildMI(*BB, BB->getFirstTerminator(), - TM.getInstrInfo()->get(X86::FP_REG_KILL)); - ++NumFPKill; - } + // Finally, if we found any FP code, emit the FP_REG_KILL instruction. + if (ContainsFPCode) { + BuildMI(*MBBI, MBBI->getFirstTerminator(), + TM.getInstrInfo()->get(X86::FP_REG_KILL)); + ++NumFPKill; + } + } while (&*(MBBI++) != BB); } /// MatchAddress - Add the specified node to the specified addressing mode, From evan.cheng at apple.com Mon Sep 24 18:49:00 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 Sep 2007 01:49:00 -0000 Subject: [llvm-commits] [llvm] r42282 - in /llvm/trunk: lib/Target/TargetSelectionDAG.td utils/TableGen/DAGISelEmitter.cpp Message-ID: <200709250149.l8P1n0ap008699@zion.cs.uiuc.edu> Author: evancheng Date: Mon Sep 24 20:48:59 2007 New Revision: 42282 URL: http://llvm.org/viewvc/llvm-project?rev=42282&view=rev Log: Rename keyword "modify" -> "implicit". Modified: llvm/trunk/lib/Target/TargetSelectionDAG.td llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Modified: llvm/trunk/lib/Target/TargetSelectionDAG.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetSelectionDAG.td?rev=42282&r1=42281&r2=42282&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetSelectionDAG.td (original) +++ llvm/trunk/lib/Target/TargetSelectionDAG.td Mon Sep 24 20:48:59 2007 @@ -197,7 +197,7 @@ } def set; -def modify; +def implicit; def parallel; def node; def srcvalue; Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=42282&r1=42281&r2=42282&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Mon Sep 24 20:48:59 2007 @@ -691,7 +691,7 @@ MadeChange |= UpdateNodeType(MVT::isVoid, TP); } return MadeChange; - } else if (getOperator()->getName() == "modify" || + } else if (getOperator()->getName() == "implicit" || getOperator()->getName() == "parallel") { bool MadeChange = false; for (unsigned i = 0; i < getNumChildren(); ++i) @@ -976,7 +976,7 @@ !Operator->isSubClassOf("SDNodeXForm") && !Operator->isSubClassOf("Intrinsic") && Operator->getName() != "set" && - Operator->getName() != "modify" && + Operator->getName() != "implicit" && Operator->getName() != "parallel") error("Unrecognized node '" + Operator->getName() + "'!"); @@ -1385,15 +1385,15 @@ if (!isUse && Pat->getTransformFn()) I->error("Cannot specify a transform function for a non-input value!"); return; - } else if (Pat->getOperator()->getName() == "modify") { + } else if (Pat->getOperator()->getName() == "implicit") { for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) { TreePatternNode *Dest = Pat->getChild(i); if (!Dest->isLeaf()) - I->error("modify value should be a register!"); + I->error("implicitly defined value should be a register!"); DefInit *Val = dynamic_cast(Dest->getLeafValue()); if (!Val || !Val->getDef()->isSubClassOf("Register")) - I->error("modify value should be a register!"); + I->error("implicitly defined value should be a register!"); InstImpResults.push_back(Val->getDef()); } return; @@ -2789,7 +2789,7 @@ CodeGenInstruction &II = CGT.getInstruction(Op->getName()); const DAGInstruction &Inst = ISE.getInstruction(Op); TreePattern *InstPat = Inst.getPattern(); - // FIXME: Assume actual pattern comes before "modify". + // FIXME: Assume actual pattern comes before "implicit". TreePatternNode *InstPatNode = isRoot ? (InstPat ? InstPat->getTree(0) : Pattern) : (InstPat ? InstPat->getTree(0) : NULL); From evan.cheng at apple.com Mon Sep 24 18:50:04 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 Sep 2007 01:50:04 -0000 Subject: [llvm-commits] [llvm] r42283 - in /llvm/trunk: include/llvm/Target/TargetOptions.h lib/Target/TargetMachine.cpp Message-ID: <200709250150.l8P1o4KI008745@zion.cs.uiuc.edu> Author: evancheng Date: Mon Sep 24 20:50:04 2007 New Revision: 42283 URL: http://llvm.org/viewvc/llvm-project?rev=42283&view=rev Log: New temporary option -new-cc-modeling-scheme to test the new cc modeling scheme. Modified: llvm/trunk/include/llvm/Target/TargetOptions.h llvm/trunk/lib/Target/TargetMachine.cpp Modified: llvm/trunk/include/llvm/Target/TargetOptions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetOptions.h?rev=42283&r1=42282&r2=42283&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetOptions.h (original) +++ llvm/trunk/include/llvm/Target/TargetOptions.h Mon Sep 24 20:50:04 2007 @@ -73,6 +73,10 @@ /// ExceptionHandling - This flag indicates that exception information should /// be emitted. extern bool ExceptionHandling; + + /// NewCCModeling - This temporary flag indicates whether to use the new + /// condition code modeling scheme. + extern bool NewCCModeling; } // End llvm namespace Modified: llvm/trunk/lib/Target/TargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetMachine.cpp?rev=42283&r1=42282&r2=42283&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetMachine.cpp (original) +++ llvm/trunk/lib/Target/TargetMachine.cpp Mon Sep 24 20:50:04 2007 @@ -31,6 +31,7 @@ bool UseSoftFloat; bool NoZerosInBSS; bool ExceptionHandling; + bool NewCCModeling; Reloc::Model RelocationModel; CodeModel::Model CMModel; } @@ -116,6 +117,11 @@ clEnumValN(CodeModel::Large, "large", " Large code model"), clEnumValEnd)); + cl::opt + EnableNewCCModeling("new-cc-modeling-scheme", + cl::desc("New CC modeling scheme."), + cl::location(NewCCModeling), + cl::init(false)); } //--------------------------------------------------------------------------- From evan.cheng at apple.com Mon Sep 24 18:54:36 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 Sep 2007 01:54:36 -0000 Subject: [llvm-commits] [llvm] r42284 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/SelectionDAG/ScheduleDAG.cpp lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Message-ID: <200709250154.l8P1sa0K008858@zion.cs.uiuc.edu> Author: evancheng Date: Mon Sep 24 20:54:36 2007 New Revision: 42284 URL: http://llvm.org/viewvc/llvm-project?rev=42284&view=rev Log: Added major new capabilities to scheduler (only BURR for now) to support physical register dependency. The BURR scheduler can now backtrace and duplicate instructions in order to avoid "expensive / impossible to copy" values (e.g. status flag EFLAGS for x86) from being clobbered. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=42284&r1=42283&r2=42284&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Mon Sep 24 20:54:36 2007 @@ -79,12 +79,13 @@ /// SDep - Scheduling dependency. It keeps track of dependent nodes, /// cost of the depdenency, etc. struct SDep { - SUnit *Dep; // Dependent - either a predecessor or a successor. - bool isCtrl; // True iff it's a control dependency. - unsigned PhyReg; // If non-zero, this dep is a phy register dependency. - int Cost; // Cost of the dependency. - SDep(SUnit *d, bool c, unsigned r, int t) - : Dep(d), isCtrl(c), PhyReg(r), Cost(t) {} + SUnit *Dep; // Dependent - either a predecessor or a successor. + unsigned Reg; // If non-zero, this dep is a phy register dependency. + int Cost; // Cost of the dependency. + bool isCtrl : 1; // True iff it's a control dependency. + bool isSpecial : 1; // True iff it's a special ctrl dep added during sched. + SDep(SUnit *d, unsigned r, int t, bool c, bool s) + : Dep(d), Reg(r), Cost(t), isCtrl(c), isSpecial(s) {} }; /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or @@ -92,6 +93,8 @@ struct SUnit { SDNode *Node; // Representative node. SmallVector FlaggedNodes;// All nodes flagged to Node. + unsigned InstanceNo; // Instance#. One SDNode can be multiple + // SUnit due to cloning. // Preds/Succs - The SUnits before/after us in the graph. The boolean value // is true if the edge is a token chain edge, false if it is a value edge. @@ -103,6 +106,8 @@ typedef SmallVector::const_iterator const_pred_iterator; typedef SmallVector::const_iterator const_succ_iterator; + unsigned NodeNum; // Entry # of node in the node vector. + unsigned short Latency; // Node latency. short NumPreds; // # of preds. short NumSuccs; // # of sucss. short NumPredsLeft; // # of preds not scheduled. @@ -111,42 +116,94 @@ short NumChainSuccsLeft; // # of chain succs not scheduled. bool isTwoAddress : 1; // Is a two-address instruction. bool isCommutable : 1; // Is a commutable instruction. + bool hasImplicitDefs : 1; // Has implicit physical reg defs. bool isPending : 1; // True once pending. bool isAvailable : 1; // True once available. bool isScheduled : 1; // True once scheduled. - unsigned short Latency; // Node latency. unsigned CycleBound; // Upper/lower cycle to be scheduled at. unsigned Cycle; // Once scheduled, the cycle of the op. unsigned Depth; // Node depth; unsigned Height; // Node height; - unsigned NodeNum; // Entry # of node in the node vector. SUnit(SDNode *node, unsigned nodenum) - : Node(node), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), + : Node(node), InstanceNo(0), NodeNum(nodenum), Latency(0), + NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), NumChainPredsLeft(0), NumChainSuccsLeft(0), - isTwoAddress(false), isCommutable(false), + isTwoAddress(false), isCommutable(false), hasImplicitDefs(false), isPending(false), isAvailable(false), isScheduled(false), - Latency(0), CycleBound(0), Cycle(0), Depth(0), Height(0), - NodeNum(nodenum) {} - + CycleBound(0), Cycle(0), Depth(0), Height(0) {} + /// addPred - This adds the specified node as a pred of the current node if /// not already. This returns true if this is a new pred. - bool addPred(SUnit *N, bool isCtrl, unsigned PhyReg = 0, int Cost = 1) { + bool addPred(SUnit *N, bool isCtrl, bool isSpecial, + unsigned PhyReg = 0, int Cost = 1) { for (unsigned i = 0, e = Preds.size(); i != e; ++i) - if (Preds[i].Dep == N && Preds[i].isCtrl == isCtrl) + if (Preds[i].Dep == N && + Preds[i].isCtrl == isCtrl && Preds[i].isSpecial == isSpecial) return false; - Preds.push_back(SDep(N, isCtrl, PhyReg, Cost)); + Preds.push_back(SDep(N, PhyReg, Cost, isCtrl, isSpecial)); + N->Succs.push_back(SDep(this, PhyReg, Cost, isCtrl, isSpecial)); + if (isCtrl) { + if (!N->isScheduled) + ++NumChainPredsLeft; + if (!isScheduled) + ++N->NumChainSuccsLeft; + } else { + ++NumPreds; + ++N->NumSuccs; + if (!N->isScheduled) + ++NumPredsLeft; + if (!isScheduled) + ++N->NumSuccsLeft; + } return true; } - /// addSucc - This adds the specified node as a succ of the current node if - /// not already. This returns true if this is a new succ. - bool addSucc(SUnit *N, bool isCtrl, unsigned PhyReg = 0, int Cost = 1) { + bool removePred(SUnit *N, bool isCtrl, bool isSpecial) { + for (SmallVector::iterator I = Preds.begin(), E = Preds.end(); + I != E; ++I) + if (I->Dep == N && I->isCtrl == isCtrl && I->isSpecial == isSpecial) { + bool FoundSucc = false; + for (SmallVector::iterator II = N->Succs.begin(), + EE = N->Succs.end(); II != EE; ++II) + if (II->Dep == this && + II->isCtrl == isCtrl && II->isSpecial == isSpecial) { + FoundSucc = true; + N->Succs.erase(II); + break; + } + assert(FoundSucc && "Mismatching preds / succs lists!"); + Preds.erase(I); + if (isCtrl) { + if (!N->isScheduled) + --NumChainPredsLeft; + if (!isScheduled) + --NumChainSuccsLeft; + } else { + --NumPreds; + --N->NumSuccs; + if (!N->isScheduled) + --NumPredsLeft; + if (!isScheduled) + --N->NumSuccsLeft; + } + return true; + } + return false; + } + + bool isPred(SUnit *N) { + for (unsigned i = 0, e = Preds.size(); i != e; ++i) + if (Preds[i].Dep == N) + return true; + return false; + } + + bool isSucc(SUnit *N) { for (unsigned i = 0, e = Succs.size(); i != e; ++i) - if (Succs[i].Dep == N && Succs[i].isCtrl == isCtrl) - return false; - Succs.push_back(SDep(N, isCtrl, PhyReg, Cost)); - return true; + if (Succs[i].Dep == N) + return true; + return false; } void dump(const SelectionDAG *G) const; @@ -165,20 +222,27 @@ public: virtual ~SchedulingPriorityQueue() {} - virtual void initNodes(DenseMap &SUMap, + virtual void initNodes(DenseMap > &SUMap, std::vector &SUnits) = 0; + virtual void addNode(const SUnit *SU) = 0; + virtual void updateNode(const SUnit *SU) = 0; virtual void releaseState() = 0; - + + virtual unsigned size() const = 0; virtual bool empty() const = 0; virtual void push(SUnit *U) = 0; virtual void push_all(const std::vector &Nodes) = 0; virtual SUnit *pop() = 0; + virtual void remove(SUnit *SU) = 0; + /// ScheduledNode - As each node is scheduled, this method is invoked. This /// allows the priority function to adjust the priority of node that have /// already been emitted. virtual void ScheduledNode(SUnit *Node) {} + + virtual void UnscheduledNode(SUnit *Node) {} }; class ScheduleDAG { @@ -192,7 +256,8 @@ MachineConstantPool *ConstPool; // Target constant pool std::vector Sequence; // The schedule. Null SUnit*'s // represent noop instructions. - DenseMap SUnitMap; // SDNode to SUnit mapping (n -> 1). + DenseMap > SUnitMap; + // SDNode to SUnit mapping (n -> n). std::vector SUnits; // The scheduling units. SmallSet CommuteSet; // Nodes the should be commuted. @@ -232,6 +297,10 @@ return &SUnits.back(); } + /// Clone - Creates a clone of the specified SUnit. It does not copy the + /// predecessors / successors info nor the temporary scheduling states. + SUnit *Clone(SUnit *N); + /// BuildSchedUnits - Build SUnits from the selection dag that we are input. /// This SUnit graph is similar to the SelectionDAG, but represents flagged /// together nodes with a single SUnit. @@ -256,7 +325,8 @@ /// VRBaseMap contains, for each already emitted node, the first virtual /// register number for the results of the node. /// - void EmitNode(SDNode *Node, DenseMap &VRBaseMap); + void EmitNode(SDNode *Node, unsigned InstNo, + DenseMap &VRBaseMap); /// EmitNoop - Emit a noop instruction. /// @@ -264,7 +334,8 @@ /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an /// implicit physical register output. - void EmitCopyFromReg(SDNode *Node, unsigned ResNo, unsigned SrcReg, + void EmitCopyFromReg(SDNode *Node, unsigned ResNo, unsigned InstNo, + unsigned SrcReg, DenseMap &VRBaseMap); void CreateVirtualRegisters(SDNode *Node, 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=42284&r1=42283&r2=42284&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Mon Sep 24 20:54:36 2007 @@ -27,6 +27,65 @@ #include "llvm/Support/MathExtras.h" using namespace llvm; + +/// getPhysicalRegisterRegClass - Returns the Register Class of a physical +/// register. +static const TargetRegisterClass *getPhysicalRegisterRegClass( + const MRegisterInfo *MRI, + MVT::ValueType VT, + unsigned reg) { + assert(MRegisterInfo::isPhysicalRegister(reg) && + "reg must be a physical register"); + // Pick the register class of the right type that contains this physreg. + for (MRegisterInfo::regclass_iterator I = MRI->regclass_begin(), + E = MRI->regclass_end(); I != E; ++I) + if ((*I)->hasType(VT) && (*I)->contains(reg)) + return *I; + assert(false && "Couldn't find the register class"); + return 0; +} + + +/// CheckForPhysRegDependency - Check if the dependency between def and use of +/// a specified operand is a physical register dependency. If so, returns the +/// register and the cost of copying the register. +static void CheckForPhysRegDependency(SDNode *Def, SDNode *Use, unsigned Op, + const MRegisterInfo *MRI, + const TargetInstrInfo *TII, + unsigned &PhysReg, int &Cost) { + if (Op != 2 || Use->getOpcode() != ISD::CopyToReg) + return; + + unsigned Reg = cast(Use->getOperand(1))->getReg(); + if (MRegisterInfo::isVirtualRegister(Reg)) + return; + + unsigned ResNo = Use->getOperand(2).ResNo; + if (Def->isTargetOpcode()) { + const TargetInstrDescriptor &II = TII->get(Def->getTargetOpcode()); + if (ResNo >= II.numDefs && + II.ImplicitDefs[ResNo - II.numDefs] == Reg) { + PhysReg = Reg; + const TargetRegisterClass *RC = + getPhysicalRegisterRegClass(MRI, Def->getValueType(ResNo), Reg); + Cost = RC->getCopyCost(); + } + } +} + +SUnit *ScheduleDAG::Clone(SUnit *Old) { + SUnit *SU = NewSUnit(Old->Node); + for (unsigned i = 0, e = SU->FlaggedNodes.size(); i != e; ++i) + SU->FlaggedNodes.push_back(SU->FlaggedNodes[i]); + SU->InstanceNo = SUnitMap[Old->Node].size(); + SU->Latency = Old->Latency; + SU->isTwoAddress = Old->isTwoAddress; + SU->isCommutable = Old->isCommutable; + SU->hasImplicitDefs = Old->hasImplicitDefs; + SUnitMap[Old->Node].push_back(SU); + return SU; +} + /// BuildSchedUnits - Build SUnits from the selection dag that we are input. /// This SUnit graph is similar to the SelectionDAG, but represents flagged /// together nodes with a single SUnit. @@ -44,7 +103,7 @@ continue; // If this node has already been processed, stop now. - if (SUnitMap[NI]) continue; + if (SUnitMap[NI].size()) continue; SUnit *NodeSUnit = NewSUnit(NI); @@ -59,7 +118,7 @@ do { N = N->getOperand(N->getNumOperands()-1).Val; NodeSUnit->FlaggedNodes.push_back(N); - SUnitMap[N] = NodeSUnit; + SUnitMap[N].push_back(NodeSUnit); } while (N->getNumOperands() && N->getOperand(N->getNumOperands()-1).getValueType()== MVT::Flag); std::reverse(NodeSUnit->FlaggedNodes.begin(), @@ -79,7 +138,7 @@ if (FlagVal.isOperand(*UI)) { HasFlagUse = true; NodeSUnit->FlaggedNodes.push_back(N); - SUnitMap[N] = NodeSUnit; + SUnitMap[N].push_back(NodeSUnit); N = *UI; break; } @@ -89,7 +148,7 @@ // Now all flagged nodes are in FlaggedNodes and N is the bottom-most node. // Update the SUnit NodeSUnit->Node = N; - SUnitMap[N] = NodeSUnit; + SUnitMap[N].push_back(NodeSUnit); // Compute the latency for the node. We use the sum of the latencies for // all nodes flagged together into this SUnit. @@ -125,13 +184,16 @@ if (MainNode->isTargetOpcode()) { unsigned Opc = MainNode->getTargetOpcode(); - for (unsigned i = 0, ee = TII->getNumOperands(Opc); i != ee; ++i) { - if (TII->getOperandConstraint(Opc, i, TOI::TIED_TO) != -1) { + const TargetInstrDescriptor &TID = TII->get(Opc); + if (TID.ImplicitDefs) + SU->hasImplicitDefs = true; + for (unsigned i = 0; i != TID.numOperands; ++i) { + if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) { SU->isTwoAddress = true; break; } } - if (TII->isCommutableInstr(Opc)) + if (TID.Flags & M_COMMUTABLE) SU->isCommutable = true; } @@ -141,34 +203,25 @@ for (unsigned n = 0, e = SU->FlaggedNodes.size(); n != e; ++n) { SDNode *N = SU->FlaggedNodes[n]; + if (N->isTargetOpcode() && TII->getImplicitDefs(N->getTargetOpcode())) + SU->hasImplicitDefs = true; for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { SDNode *OpN = N->getOperand(i).Val; if (isPassiveNode(OpN)) continue; // Not scheduled. - SUnit *OpSU = SUnitMap[OpN]; + SUnit *OpSU = SUnitMap[OpN].front(); assert(OpSU && "Node has no SUnit!"); if (OpSU == SU) continue; // In the same group. MVT::ValueType OpVT = N->getOperand(i).getValueType(); assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!"); bool isChain = OpVT == MVT::Other; - - if (SU->addPred(OpSU, isChain)) { - if (!isChain) { - SU->NumPreds++; - SU->NumPredsLeft++; - } else { - SU->NumChainPredsLeft++; - } - } - if (OpSU->addSucc(SU, isChain)) { - if (!isChain) { - OpSU->NumSuccs++; - OpSU->NumSuccsLeft++; - } else { - OpSU->NumChainSuccsLeft++; - } - } + + unsigned PhysReg = 0; + int Cost = 1; + // Determine if this is a physical register dependency. + CheckForPhysRegDependency(OpN, N, i, MRI, TII, PhysReg, Cost); + SU->addPred(OpSU, isChain, false, PhysReg, Cost); } } @@ -200,7 +253,7 @@ void ScheduleDAG::CalculateHeights() { std::vector > WorkList; - SUnit *Root = SUnitMap[DAG.getRoot().Val]; + SUnit *Root = SUnitMap[DAG.getRoot().Val].front(); WorkList.push_back(std::make_pair(Root, 0U)); while (!WorkList.empty()) { @@ -254,27 +307,14 @@ ? TII->getPointerRegClass() : MRI->getRegClass(toi.RegClass); } -// Returns the Register Class of a physical register -static const TargetRegisterClass *getPhysicalRegisterRegClass( - const MRegisterInfo *MRI, - MVT::ValueType VT, - unsigned reg) { - assert(MRegisterInfo::isPhysicalRegister(reg) && - "reg must be a physical register"); - // Pick the register class of the right type that contains this physreg. - for (MRegisterInfo::regclass_iterator I = MRI->regclass_begin(), - E = MRI->regclass_end(); I != E; ++I) - if ((*I)->hasType(VT) && (*I)->contains(reg)) - return *I; - assert(false && "Couldn't find the register class"); - return 0; -} - -void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo, unsigned SrcReg, +void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo, + unsigned InstanceNo, unsigned SrcReg, DenseMap &VRBaseMap) { unsigned VRBase = 0; if (MRegisterInfo::isVirtualRegister(SrcReg)) { // Just use the input register directly! + if (InstanceNo > 0) + VRBaseMap.erase(SDOperand(Node, ResNo)); bool isNew = VRBaseMap.insert(std::make_pair(SDOperand(Node,ResNo),SrcReg)); assert(isNew && "Node emitted out of order - early"); return; @@ -282,32 +322,54 @@ // If the node is only used by a CopyToReg and the dest reg is a vreg, use // the CopyToReg'd destination register instead of creating a new vreg. + bool MatchReg = true; for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); UI != E; ++UI) { SDNode *Use = *UI; + bool Match = true; if (Use->getOpcode() == ISD::CopyToReg && Use->getOperand(2).Val == Node && Use->getOperand(2).ResNo == ResNo) { unsigned DestReg = cast(Use->getOperand(1))->getReg(); if (MRegisterInfo::isVirtualRegister(DestReg)) { VRBase = DestReg; - break; + Match = false; + } else if (DestReg != SrcReg) + Match = false; + } else { + for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) { + SDOperand Op = Use->getOperand(i); + if (Op.Val != Node) + continue; + MVT::ValueType VT = Node->getValueType(Op.ResNo); + if (VT != MVT::Other && VT != MVT::Flag) + Match = false; } } + MatchReg &= Match; + if (VRBase) + break; } - // Figure out the register class to create for the destreg. const TargetRegisterClass *TRC = 0; - if (VRBase) { + // Figure out the register class to create for the destreg. + if (VRBase) TRC = RegMap->getRegClass(VRBase); - } else { + else TRC = getPhysicalRegisterRegClass(MRI, Node->getValueType(ResNo), SrcReg); - + + // If all uses are reading from the src physical register and copying the + // register is either impossible or very expensive, then don't create a copy. + if (MatchReg && TRC->getCopyCost() < 0) { + VRBase = SrcReg; + } else { // Create the reg, emit the copy. VRBase = RegMap->createVirtualRegister(TRC); + MRI->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, TRC); } - MRI->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, TRC); + if (InstanceNo > 0) + VRBaseMap.erase(SDOperand(Node, ResNo)); bool isNew = VRBaseMap.insert(std::make_pair(SDOperand(Node,ResNo), VRBase)); assert(isNew && "Node emitted out of order - early"); } @@ -611,7 +673,7 @@ /// EmitNode - Generate machine code for an node and needed dependencies. /// -void ScheduleDAG::EmitNode(SDNode *Node, +void ScheduleDAG::EmitNode(SDNode *Node, unsigned InstanceNo, DenseMap &VRBaseMap) { // If machine instruction if (Node->isTargetOpcode()) { @@ -677,7 +739,7 @@ for (unsigned i = II.numDefs; i < NumResults; ++i) { unsigned Reg = II.ImplicitDefs[i - II.numDefs]; if (Node->hasAnyUseOfValue(i)) - EmitCopyFromReg(Node, i, Reg, VRBaseMap); + EmitCopyFromReg(Node, i, InstanceNo, Reg, VRBaseMap); } } } else { @@ -713,7 +775,7 @@ } case ISD::CopyFromReg: { unsigned SrcReg = cast(Node->getOperand(1))->getReg(); - EmitCopyFromReg(Node, 0, SrcReg, VRBaseMap); + EmitCopyFromReg(Node, 0, InstanceNo, SrcReg, VRBaseMap); break; } case ISD::INLINEASM: { @@ -802,9 +864,9 @@ DenseMap VRBaseMap; for (unsigned i = 0, e = Sequence.size(); i != e; i++) { if (SUnit *SU = Sequence[i]) { - for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++) - EmitNode(SU->FlaggedNodes[j], VRBaseMap); - EmitNode(SU->Node, VRBaseMap); + for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; ++j) + EmitNode(SU->FlaggedNodes[j], SU->InstanceNo, VRBaseMap); + EmitNode(SU->Node, SU->InstanceNo, VRBaseMap); } else { // Null SUnit* is a noop. EmitNoop(); @@ -869,7 +931,10 @@ cerr << " ch #"; else cerr << " val #"; - cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")\n"; + cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")"; + if (I->isSpecial) + cerr << " *"; + cerr << "\n"; } } if (Succs.size() != 0) { @@ -880,7 +945,10 @@ cerr << " ch #"; else cerr << " val #"; - cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")\n"; + cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")"; + if (I->isSpecial) + cerr << " *"; + cerr << "\n"; } } cerr << "\n"; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=42284&r1=42283&r2=42284&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Mon Sep 24 20:54:36 2007 @@ -168,7 +168,7 @@ /// schedulers. void ScheduleDAGList::ListScheduleTopDown() { unsigned CurCycle = 0; - SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; + SUnit *Entry = SUnitMap[DAG.getEntryNode().Val].front(); // All leaves to Available queue. for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { @@ -328,12 +328,24 @@ LatencyPriorityQueue() : Queue(latency_sort(this)) { } - void initNodes(DenseMap &sumap, + void initNodes(DenseMap > &sumap, std::vector &sunits) { SUnits = &sunits; // Calculate node priorities. CalculatePriorities(); } + + void addNode(const SUnit *SU) { + Latencies.resize(SUnits->size(), -1); + NumNodesSolelyBlocking.resize(SUnits->size(), 0); + CalcLatency(*SU); + } + + void updateNode(const SUnit *SU) { + Latencies[SU->NodeNum] = -1; + CalcLatency(*SU); + } + void releaseState() { SUnits = 0; Latencies.clear(); @@ -349,6 +361,8 @@ return NumNodesSolelyBlocking[NodeNum]; } + unsigned size() const { return Queue.size(); } + bool empty() const { return Queue.empty(); } virtual void push(SUnit *U) { @@ -368,22 +382,10 @@ return V; } - // ScheduledNode - As nodes are scheduled, we look to see if there are any - // successor nodes that have a single unscheduled predecessor. If so, that - // single predecessor has a higher priority, since scheduling it will make - // the node available. - void ScheduledNode(SUnit *Node); - -private: - void CalculatePriorities(); - int CalcLatency(const SUnit &SU); - void AdjustPriorityOfUnscheduledPreds(SUnit *SU); - SUnit *getSingleUnscheduledPred(SUnit *SU); - - /// RemoveFromPriorityQueue - This is a really inefficient way to remove a - /// node from a priority queue. We should roll our own heap to make this - /// better or something. - void RemoveFromPriorityQueue(SUnit *SU) { + /// remove - This is a really inefficient way to remove a node from a + /// priority queue. We should roll our own heap to make this better or + /// something. + void remove(SUnit *SU) { std::vector Temp; assert(!Queue.empty() && "Not in queue!"); @@ -400,6 +402,18 @@ for (unsigned i = 0, e = Temp.size(); i != e; ++i) Queue.push(Temp[i]); } + + // ScheduledNode - As nodes are scheduled, we look to see if there are any + // successor nodes that have a single unscheduled predecessor. If so, that + // single predecessor has a higher priority, since scheduling it will make + // the node available. + void ScheduledNode(SUnit *Node); + +private: + void CalculatePriorities(); + int CalcLatency(const SUnit &SU); + void AdjustPriorityOfUnscheduledPreds(SUnit *SU); + SUnit *getSingleUnscheduledPred(SUnit *SU); }; } @@ -507,7 +521,7 @@ // Okay, we found a single predecessor that is available, but not scheduled. // Since it is available, it must be in the priority queue. First remove it. - RemoveFromPriorityQueue(OnlyAvailablePred); + remove(OnlyAvailablePred); // Reinsert the node into the priority queue, which recomputes its // NumNodesSolelyBlocking value. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=42284&r1=42283&r2=42284&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Sep 24 20:54:36 2007 @@ -25,6 +25,7 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Compiler.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include #include @@ -52,9 +53,16 @@ bool isBottomUp; /// AvailableQueue - The priority queue to use for the available SUnits. - /// + ///a SchedulingPriorityQueue *AvailableQueue; + /// LiveRegs / LiveRegDefs - A set of physical registers and their definition + /// that are "live". These nodes must be scheduled before any other nodes that + /// modifies the registers can be scheduled. + SmallSet LiveRegs; + std::vector LiveRegDefs; + std::vector LiveRegCycles; + public: ScheduleDAGRRList(SelectionDAG &dag, MachineBasicBlock *bb, const TargetMachine &tm, bool isbottomup, @@ -72,8 +80,13 @@ private: void ReleasePred(SUnit *PredSU, bool isChain, unsigned CurCycle); void ReleaseSucc(SUnit *SuccSU, bool isChain, unsigned CurCycle); + void CapturePred(SUnit *PredSU, SUnit *SU, bool isChain); void ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle); void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); + void UnscheduleNodeBottomUp(SUnit *SU); + SUnit *BackTrackBottomUp(SUnit*, unsigned, unsigned&, bool&); + SUnit *CopyAndMoveSuccessors(SUnit *SU); + bool DelayForLiveRegsBottomUp(SUnit *SU, unsigned &CurCycle); void ListScheduleTopDown(); void ListScheduleBottomUp(); void CommuteNodesToReducePressure(); @@ -84,7 +97,10 @@ /// Schedule - Schedule the DAG using list scheduling. void ScheduleDAGRRList::Schedule() { DOUT << "********** List Scheduling **********\n"; - + + LiveRegDefs.resize(MRI->getNumRegs(), NULL); + LiveRegCycles.resize(MRI->getNumRegs(), 0); + // Build scheduling units. BuildSchedUnits(); @@ -130,7 +146,7 @@ continue; SDNode *OpN = SU->Node->getOperand(j).Val; - SUnit *OpSU = SUnitMap[OpN]; + SUnit *OpSU = SUnitMap[OpN][SU->InstanceNo]; if (OpSU && OperandSeen.count(OpSU) == 1) { // Ok, so SU is not the last use of OpSU, but SU is two-address so // it will clobber OpSU. Try to commute SU if no other source operands @@ -139,7 +155,7 @@ for (unsigned k = 0; k < NumOps; ++k) { if (k != j) { OpN = SU->Node->getOperand(k).Val; - OpSU = SUnitMap[OpN]; + OpSU = SUnitMap[OpN][SU->InstanceNo]; if (OpSU && OperandSeen.count(OpSU) == 1) { DoCommute = false; break; @@ -178,9 +194,9 @@ PredSU->CycleBound = std::max(PredSU->CycleBound, CurCycle + PredSU->Latency); if (!isChain) - PredSU->NumSuccsLeft--; + --PredSU->NumSuccsLeft; else - PredSU->NumChainSuccsLeft--; + --PredSU->NumChainSuccsLeft; #ifndef NDEBUG if (PredSU->NumSuccsLeft < 0 || PredSU->NumChainSuccsLeft < 0) { @@ -209,19 +225,273 @@ SU->Cycle = CurCycle; AvailableQueue->ScheduledNode(SU); - Sequence.push_back(SU); // Bottom up: release predecessors for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) + I != E; ++I) { ReleasePred(I->Dep, I->isCtrl, CurCycle); + if (I->Cost < 0) { + // This is a physical register dependency and it's impossible or + // expensive to copy the register. Make sure nothing that can + // clobber the register is scheduled between the predecessor and + // this node. + if (LiveRegs.insert(I->Reg)) { + LiveRegDefs[I->Reg] = I->Dep; + LiveRegCycles[I->Reg] = CurCycle; + } + } + } + + // Release all the implicit physical register defs that are live. + for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); + I != E; ++I) { + if (I->Cost < 0) { + if (LiveRegCycles[I->Reg] == I->Dep->Cycle) { + LiveRegs.erase(I->Reg); + assert(LiveRegDefs[I->Reg] == SU && + "Physical register dependency violated?"); + LiveRegDefs[I->Reg] = NULL; + LiveRegCycles[I->Reg] = 0; + } + } + } + SU->isScheduled = true; } -/// isReady - True if node's lower cycle bound is less or equal to the current -/// scheduling cycle. Always true if all nodes have uniform latency 1. -static inline bool isReady(SUnit *SU, unsigned CurCycle) { - return SU->CycleBound <= CurCycle; +/// CapturePred - This does the opposite of ReleasePred. Since SU is being +/// unscheduled, incrcease the succ left count of its predecessors. Remove +/// them from AvailableQueue if necessary. +void ScheduleDAGRRList::CapturePred(SUnit *PredSU, SUnit *SU, bool isChain) { + PredSU->CycleBound = 0; + for (SUnit::succ_iterator I = PredSU->Succs.begin(), E = PredSU->Succs.end(); + I != E; ++I) { + if (I->Dep == SU) + continue; + PredSU->CycleBound = std::max(PredSU->CycleBound, + I->Dep->Cycle + PredSU->Latency); + } + + if (PredSU->isAvailable) { + PredSU->isAvailable = false; + if (!PredSU->isPending) + AvailableQueue->remove(PredSU); + } + + if (!isChain) + ++PredSU->NumSuccsLeft; + else + ++PredSU->NumChainSuccsLeft; +} + +/// UnscheduleNodeBottomUp - Remove the node from the schedule, update its and +/// its predecessor states to reflect the change. +void ScheduleDAGRRList::UnscheduleNodeBottomUp(SUnit *SU) { + DOUT << "*** Unscheduling [" << SU->Cycle << "]: "; + DEBUG(SU->dump(&DAG)); + + AvailableQueue->UnscheduledNode(SU); + + for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); + I != E; ++I) { + CapturePred(I->Dep, SU, I->isCtrl); + if (I->Cost < 0 && SU->Cycle == LiveRegCycles[I->Reg]) { + LiveRegs.erase(I->Reg); + assert(LiveRegDefs[I->Reg] == I->Dep && + "Physical register dependency violated?"); + LiveRegDefs[I->Reg] = NULL; + LiveRegCycles[I->Reg] = 0; + } + } + + for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); + I != E; ++I) { + if (I->Cost < 0) { + if (LiveRegs.insert(I->Reg)) { + assert(!LiveRegDefs[I->Reg] && + "Physical register dependency violated?"); + LiveRegDefs[I->Reg] = SU; + } + if (I->Dep->Cycle < LiveRegCycles[I->Reg]) + LiveRegCycles[I->Reg] = I->Dep->Cycle; + } + } + + SU->Cycle = 0; + SU->isScheduled = false; + SU->isAvailable = true; + AvailableQueue->push(SU); +} + +/// BackTrackBottomUp - Back track scheduling to a previous cycle specified in +/// BTCycle in order to schedule a specific node. Returns the last unscheduled +/// SUnit. Also returns if a successor is unscheduled in the process. +SUnit *ScheduleDAGRRList::BackTrackBottomUp(SUnit *SU, unsigned BTCycle, + unsigned &CurCycle, bool &SuccUnsched) { + SuccUnsched = false; + SUnit *OldSU = NULL; + while (CurCycle > BTCycle) { + OldSU = Sequence.back(); + Sequence.pop_back(); + if (SU->isSucc(OldSU)) + SuccUnsched = true; + UnscheduleNodeBottomUp(OldSU); + --CurCycle; + } + + + if (SU->isSucc(OldSU)) { + assert(false && "Something is wrong!"); + abort(); + } + + return OldSU; +} + +/// isSafeToCopy - True if the SUnit for the given SDNode can safely cloned, +/// i.e. the node does not produce a flag, it does not read a flag and it does +/// not have an incoming chain. +static bool isSafeToCopy(SDNode *N) { + for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) + if (N->getValueType(i) == MVT::Flag) + return false; + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + const SDOperand &Op = N->getOperand(i); + MVT::ValueType VT = Op.Val->getValueType(Op.ResNo); + if (VT == MVT::Other || VT == MVT::Flag) + return false; + } + + return true; +} + +/// CopyAndMoveSuccessors - Clone the specified node and move its scheduled +/// successors to the newly created node. +SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) { + SUnit *NewSU = Clone(SU); + + // New SUnit has the exact same predecessors. + for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); + I != E; ++I) + if (!I->isSpecial) { + NewSU->addPred(I->Dep, I->isCtrl, false, I->Reg, I->Cost); + NewSU->Depth = std::max(NewSU->Depth, I->Dep->Depth+1); + } + + // Only copy scheduled successors. Cut them from old node's successor + // list and move them over. + SmallVector DelDeps; + for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); + I != E; ++I) { + if (I->isSpecial) + continue; + NewSU->Height = std::max(NewSU->Height, I->Dep->Height+1); + if (I->Dep->isScheduled) { + I->Dep->addPred(NewSU, I->isCtrl, false, I->Reg, I->Cost); + DelDeps.push_back(I); + } + } + for (unsigned i = 0, e = DelDeps.size(); i != e; ++i) { + SUnit *Succ = DelDeps[i]->Dep; + bool isCtrl = DelDeps[i]->isCtrl; + Succ->removePred(SU, isCtrl, false); + } + + AvailableQueue->updateNode(SU); + AvailableQueue->addNode(NewSU); + + return NewSU; +} + +/// DelayForLiveRegsBottomUp - Returns true if it is necessary to delay +/// scheduling of the given node to satisfy live physical register dependencies. +/// If the specific node is the last one that's available to schedule, do +/// whatever is necessary (i.e. backtracking or cloning) to make it possible. +bool ScheduleDAGRRList::DelayForLiveRegsBottomUp(SUnit *SU, unsigned &CurCycle){ + if (LiveRegs.empty()) + return false; + + // If this node would clobber any "live" register, then it's not ready. + // However, if this is the last "available" node, then we may have to + // backtrack. + bool MustSched = AvailableQueue->empty(); + SmallVector LRegs; + for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); + I != E; ++I) { + if (I->Cost < 0) { + unsigned Reg = I->Reg; + if (LiveRegs.count(Reg) && LiveRegDefs[Reg] != I->Dep) + LRegs.push_back(Reg); + for (const unsigned *Alias = MRI->getAliasSet(Reg); + *Alias; ++Alias) + if (LiveRegs.count(*Alias) && LiveRegDefs[*Alias] != I->Dep) + LRegs.push_back(*Alias); + } + } + + for (unsigned i = 0, e = SU->FlaggedNodes.size()+1; i != e; ++i) { + SDNode *Node = (i == 0) ? SU->Node : SU->FlaggedNodes[i-1]; + if (!Node->isTargetOpcode()) + continue; + const TargetInstrDescriptor &TID = TII->get(Node->getTargetOpcode()); + if (!TID.ImplicitDefs) + continue; + for (const unsigned *Reg = TID.ImplicitDefs; *Reg; ++Reg) { + if (LiveRegs.count(*Reg) && LiveRegDefs[*Reg] != SU) + LRegs.push_back(*Reg); + for (const unsigned *Alias = MRI->getAliasSet(*Reg); + *Alias; ++Alias) + if (LiveRegs.count(*Alias) && LiveRegDefs[*Alias] != SU) + LRegs.push_back(*Alias); + } + } + + if (MustSched && !LRegs.empty()) { + // We have made a mistake by scheduling some nodes too early. Now we must + // schedule the current node which will end up clobbering some live + // registers that are expensive / impossible to copy. Try unscheduling + // up to the point where it's safe to schedule the current node. + unsigned LiveCycle = CurCycle; + for (unsigned i = 0, e = LRegs.size(); i != e; ++i) { + unsigned Reg = LRegs[i]; + unsigned LCycle = LiveRegCycles[Reg]; + LiveCycle = std::min(LiveCycle, LCycle); + } + + if (SU->CycleBound < LiveCycle) { + bool SuccUnsched = false; + SUnit *OldSU = BackTrackBottomUp(SU, LiveCycle, CurCycle, SuccUnsched); + // Force the current node to be scheduled before the node that + // requires the physical reg dep. + if (OldSU->isAvailable) { + OldSU->isAvailable = false; + AvailableQueue->remove(OldSU); + } + SU->addPred(OldSU, true, true); + // If a successor has been unscheduled, then it's not possible to + // schedule the current node. + return SuccUnsched; + } else { + // Try duplicating the nodes that produces these "expensive to copy" + // values to break the dependency. + for (unsigned i = 0, e = LRegs.size(); i != e; ++i) { + unsigned Reg = LRegs[i]; + SUnit *LRDef = LiveRegDefs[Reg]; + if (isSafeToCopy(LRDef->Node)) { + SUnit *NewDef = CopyAndMoveSuccessors(LRDef); + LiveRegDefs[Reg] = NewDef; + NewDef->addPred(SU, true, true); + SU->isAvailable = false; + AvailableQueue->push(NewDef); + } else { + assert(false && "Expensive copying is required?"); + abort(); + } + } + return true; + } + } + return !LRegs.empty(); } /// ListScheduleBottomUp - The main loop of list scheduling for bottom-up @@ -229,30 +499,49 @@ void ScheduleDAGRRList::ListScheduleBottomUp() { unsigned CurCycle = 0; // Add root to Available queue. - AvailableQueue->push(SUnitMap[DAG.getRoot().Val]); + SUnit *RootSU = SUnitMap[DAG.getRoot().Val].front(); + RootSU->isAvailable = true; + AvailableQueue->push(RootSU); // While Available queue is not empty, grab the node with the highest // priority. If it is not ready put it back. Schedule the node. - std::vector NotReady; + SmallVector NotReady; while (!AvailableQueue->empty()) { - SUnit *CurNode = AvailableQueue->pop(); - while (CurNode && !isReady(CurNode, CurCycle)) { - NotReady.push_back(CurNode); - CurNode = AvailableQueue->pop(); + SUnit *CurSU = AvailableQueue->pop(); + while (CurSU) { + if (CurSU->CycleBound <= CurCycle) + if (!DelayForLiveRegsBottomUp(CurSU, CurCycle)) + break; + + // Verify node is still ready. It may not be in case the + // scheduler has backtracked. + if (CurSU->isAvailable) { + CurSU->isPending = true; + NotReady.push_back(CurSU); + } + CurSU = AvailableQueue->pop(); } // Add the nodes that aren't ready back onto the available list. - AvailableQueue->push_all(NotReady); + for (unsigned i = 0, e = NotReady.size(); i != e; ++i) { + NotReady[i]->isPending = false; + if (NotReady[i]->isAvailable) + AvailableQueue->push(NotReady[i]); + } NotReady.clear(); - if (CurNode != NULL) - ScheduleNodeBottomUp(CurNode, CurCycle); - CurCycle++; + if (!CurSU) + Sequence.push_back(0); + else { + ScheduleNodeBottomUp(CurSU, CurCycle); + Sequence.push_back(CurSU); + } + ++CurCycle; } // Add entry node last if (DAG.getEntryNode().Val != DAG.getRoot().Val) { - SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; + SUnit *Entry = SUnitMap[DAG.getEntryNode().Val].front(); Sequence.push_back(Entry); } @@ -291,9 +580,9 @@ SuccSU->CycleBound = std::max(SuccSU->CycleBound, CurCycle + SuccSU->Latency); if (!isChain) - SuccSU->NumPredsLeft--; + --SuccSU->NumPredsLeft; else - SuccSU->NumChainPredsLeft--; + --SuccSU->NumChainPredsLeft; #ifndef NDEBUG if (SuccSU->NumPredsLeft < 0 || SuccSU->NumChainPredsLeft < 0) { @@ -320,7 +609,6 @@ SU->Cycle = CurCycle; AvailableQueue->ScheduledNode(SU); - Sequence.push_back(SU); // Top down: release successors for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); @@ -333,7 +621,7 @@ /// schedulers. void ScheduleDAGRRList::ListScheduleTopDown() { unsigned CurCycle = 0; - SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; + SUnit *Entry = SUnitMap[DAG.getEntryNode().Val].front(); // All leaves to Available queue. for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { @@ -346,24 +634,29 @@ // Emit the entry node first. ScheduleNodeTopDown(Entry, CurCycle); - CurCycle++; + Sequence.push_back(Entry); + ++CurCycle; // While Available queue is not empty, grab the node with the highest // priority. If it is not ready put it back. Schedule the node. std::vector NotReady; while (!AvailableQueue->empty()) { - SUnit *CurNode = AvailableQueue->pop(); - while (CurNode && !isReady(CurNode, CurCycle)) { - NotReady.push_back(CurNode); - CurNode = AvailableQueue->pop(); + SUnit *CurSU = AvailableQueue->pop(); + while (CurSU && CurSU->CycleBound > CurCycle) { + NotReady.push_back(CurSU); + CurSU = AvailableQueue->pop(); } // Add the nodes that aren't ready back onto the available list. AvailableQueue->push_all(NotReady); NotReady.clear(); - if (CurNode != NULL) - ScheduleNodeTopDown(CurNode, CurCycle); + if (!CurSU) + Sequence.push_back(0); + else { + ScheduleNodeTopDown(CurSU, CurCycle); + Sequence.push_back(CurSU); + } CurCycle++; } @@ -431,14 +724,21 @@ RegReductionPriorityQueue() : Queue(SF(this)) {} - virtual void initNodes(DenseMap &sumap, + virtual void initNodes(DenseMap > &sumap, std::vector &sunits) {} + + virtual void addNode(const SUnit *SU) {} + + virtual void updateNode(const SUnit *SU) {} + virtual void releaseState() {} virtual unsigned getNodePriority(const SUnit *SU) const { return 0; } + unsigned size() const { return Queue.size(); } + bool empty() const { return Queue.empty(); } void push(SUnit *U) { @@ -456,16 +756,33 @@ return V; } - virtual bool isDUOperand(const SUnit *SU1, const SUnit *SU2) { - return false; + /// remove - This is a really inefficient way to remove a node from a + /// priority queue. We should roll our own heap to make this better or + /// something. + void remove(SUnit *SU) { + std::vector Temp; + + assert(!Queue.empty() && "Not in queue!"); + while (Queue.top() != SU) { + Temp.push_back(Queue.top()); + Queue.pop(); + assert(!Queue.empty() && "Not in queue!"); + } + + // Remove the node from the PQ. + Queue.pop(); + + // Add all the other nodes back. + for (unsigned i = 0, e = Temp.size(); i != e; ++i) + Queue.push(Temp[i]); } }; template class VISIBILITY_HIDDEN BURegReductionPriorityQueue : public RegReductionPriorityQueue { - // SUnitMap SDNode to SUnit mapping (n -> 1). - DenseMap *SUnitMap; + // SUnitMap SDNode to SUnit mapping (n -> n). + DenseMap > *SUnitMap; // SUnits - The SUnits for the current graph. const std::vector *SUnits; @@ -478,7 +795,7 @@ explicit BURegReductionPriorityQueue(const TargetInstrInfo *tii) : TII(tii) {} - void initNodes(DenseMap &sumap, + void initNodes(DenseMap > &sumap, std::vector &sunits) { SUnitMap = &sumap; SUnits = &sunits; @@ -488,6 +805,16 @@ CalculateSethiUllmanNumbers(); } + void addNode(const SUnit *SU) { + SethiUllmanNumbers.resize(SUnits->size(), 0); + CalcNodeSethiUllmanNumber(SU); + } + + void updateNode(const SUnit *SU) { + SethiUllmanNumbers[SU->NodeNum] = 0; + CalcNodeSethiUllmanNumber(SU); + } + void releaseState() { SUnits = 0; SethiUllmanNumbers.clear(); @@ -519,18 +846,6 @@ return SethiUllmanNumbers[SU->NodeNum]; } - bool isDUOperand(const SUnit *SU1, const SUnit *SU2) { - unsigned Opc = SU1->Node->getTargetOpcode(); - unsigned NumRes = TII->getNumDefs(Opc); - unsigned NumOps = ScheduleDAG::CountOperands(SU1->Node); - for (unsigned i = 0; i != NumOps; ++i) { - if (TII->getOperandConstraint(Opc, i+NumRes, TOI::TIED_TO) == -1) - continue; - if (SU1->Node->getOperand(i).isOperand(SU2->Node)) - return true; - } - return false; - } private: bool canClobber(SUnit *SU, SUnit *Op); void AddPseudoTwoAddrDeps(); @@ -542,8 +857,8 @@ template class VISIBILITY_HIDDEN TDRegReductionPriorityQueue : public RegReductionPriorityQueue { - // SUnitMap SDNode to SUnit mapping (n -> 1). - DenseMap *SUnitMap; + // SUnitMap SDNode to SUnit mapping (n -> n). + DenseMap > *SUnitMap; // SUnits - The SUnits for the current graph. const std::vector *SUnits; @@ -554,7 +869,7 @@ public: TDRegReductionPriorityQueue() {} - void initNodes(DenseMap &sumap, + void initNodes(DenseMap > &sumap, std::vector &sunits) { SUnitMap = &sumap; SUnits = &sunits; @@ -562,6 +877,16 @@ CalculateSethiUllmanNumbers(); } + void addNode(const SUnit *SU) { + SethiUllmanNumbers.resize(SUnits->size(), 0); + CalcNodeSethiUllmanNumber(SU); + } + + void updateNode(const SUnit *SU) { + SethiUllmanNumbers[SU->NodeNum] = 0; + CalcNodeSethiUllmanNumber(SU); + } + void releaseState() { SUnits = 0; SethiUllmanNumbers.clear(); @@ -710,7 +1035,7 @@ for (unsigned i = 0; i != NumOps; ++i) { if (TII->getOperandConstraint(Opc, i+NumRes, TOI::TIED_TO) != -1) { SDNode *DU = SU->Node->getOperand(i).Val; - if (Op == (*SUnitMap)[DU]) + if (Op == (*SUnitMap)[DU][SU->InstanceNo]) return true; } } @@ -740,23 +1065,25 @@ for (unsigned j = 0; j != NumOps; ++j) { if (TII->getOperandConstraint(Opc, j+NumRes, TOI::TIED_TO) != -1) { SDNode *DU = SU->Node->getOperand(j).Val; - SUnit *DUSU = (*SUnitMap)[DU]; + SUnit *DUSU = (*SUnitMap)[DU][SU->InstanceNo]; if (!DUSU) continue; for (SUnit::succ_iterator I = DUSU->Succs.begin(),E = DUSU->Succs.end(); I != E; ++I) { if (I->isCtrl) continue; SUnit *SuccSU = I->Dep; - if (SuccSU != SU && - (!canClobber(SuccSU, DUSU) || - (!SU->isCommutable && SuccSU->isCommutable))){ - if (SuccSU->Depth == SU->Depth && !isReachable(SuccSU, SU)) { - DOUT << "Adding an edge from SU # " << SU->NodeNum - << " to SU #" << SuccSU->NodeNum << "\n"; - if (SU->addPred(SuccSU, true)) - SU->NumChainPredsLeft++; - if (SuccSU->addSucc(SU, true)) - SuccSU->NumChainSuccsLeft++; - } + // Don't constraint nodes with implicit defs. It can create cycles + // plus it may increase register pressures. + if (SuccSU == SU || SuccSU->hasImplicitDefs) + continue; + // Be conservative. Ignore if nodes aren't at the same depth. + if (SuccSU->Depth != SU->Depth) + continue; + if ((!canClobber(SuccSU, DUSU) || + (!SU->isCommutable && SuccSU->isCommutable)) && + !isReachable(SuccSU, SU)) { + DOUT << "Adding an edge from SU # " << SU->NodeNum + << " to SU #" << SuccSU->NodeNum << "\n"; + SU->addPred(SuccSU, true, true); } } } @@ -783,7 +1110,7 @@ SethiUllmanNumber = PredSethiUllman; Extra = 0; } else if (PredSethiUllman == SethiUllmanNumber && !I->isCtrl) - Extra++; + ++Extra; } SethiUllmanNumber += Extra; @@ -813,7 +1140,7 @@ EE = SuccSU->Preds.end(); II != EE; ++II) { SUnit *PredSU = II->Dep; if (!PredSU->isScheduled) - Sum++; + ++Sum; } } @@ -906,7 +1233,7 @@ SethiUllmanNumber = PredSethiUllman; Extra = 0; } else if (PredSethiUllman == SethiUllmanNumber && !I->isCtrl) - Extra++; + ++Extra; } SethiUllmanNumber += Extra; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp?rev=42284&r1=42283&r2=42284&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp Mon Sep 24 20:54:36 2007 @@ -697,9 +697,9 @@ NodeInfo *NI = Ordering[i]; if (NI->isInGroup()) { NodeGroupIterator NGI(Ordering[i]); - while (NodeInfo *NI = NGI.next()) EmitNode(NI->Node, VRBaseMap); + while (NodeInfo *NI = NGI.next()) EmitNode(NI->Node, 0, VRBaseMap); } else { - EmitNode(NI->Node, VRBaseMap); + EmitNode(NI->Node, 0, VRBaseMap); } } } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp?rev=42284&r1=42283&r2=42284&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Mon Sep 24 20:54:36 2007 @@ -281,7 +281,7 @@ GraphWriter &GW) { GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot"); if (G->DAG.getRoot().Val) - GW.emitEdge(0, -1, G->SUnitMap[G->DAG.getRoot().Val], -1, ""); + GW.emitEdge(0, -1, G->SUnitMap[G->DAG.getRoot().Val].front(), -1, ""); } }; } From evan.cheng at apple.com Mon Sep 24 18:57:46 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 Sep 2007 01:57:46 -0000 Subject: [llvm-commits] [llvm] r42285 - in /llvm/trunk/lib/Target/X86: X86FloatingPoint.cpp X86ISelLowering.cpp X86ISelLowering.h X86InstrFPStack.td X86InstrInfo.cpp X86InstrInfo.td X86InstrSSE.td X86InstrX86-64.td X86RegisterInfo.cpp Message-ID: <200709250157.l8P1vlIT008976@zion.cs.uiuc.edu> Author: evancheng Date: Mon Sep 24 20:57:46 2007 New Revision: 42285 URL: http://llvm.org/viewvc/llvm-project?rev=42285&view=rev Log: Added support for new condition code modeling scheme (i.e. physical register dependency). These are a bunch of instructions that are duplicated so the x86 backend can support both the old and new schemes at the same time. They will be deleted after all the kinks are worked out. Modified: llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h llvm/trunk/lib/Target/X86/X86InstrFPStack.td llvm/trunk/lib/Target/X86/X86InstrInfo.cpp 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.cpp Modified: llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp?rev=42285&r1=42284&r2=42285&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp Mon Sep 24 20:57:46 2007 @@ -437,6 +437,33 @@ { X86::MUL_FpI32m32 , X86::MUL_FI32m }, { X86::MUL_FpI32m64 , X86::MUL_FI32m }, { X86::MUL_FpI32m80 , X86::MUL_FI32m }, + + // TEMPORARY + { X86::NEW_CMOVBE_Fp32 , X86::CMOVBE_F }, + { X86::NEW_CMOVBE_Fp64 , X86::CMOVBE_F }, + { X86::NEW_CMOVBE_Fp80 , X86::CMOVBE_F }, + { X86::NEW_CMOVB_Fp32 , X86::CMOVB_F }, + { X86::NEW_CMOVB_Fp64 , X86::CMOVB_F }, + { X86::NEW_CMOVB_Fp80 , X86::CMOVB_F }, + { X86::NEW_CMOVE_Fp32 , X86::CMOVE_F }, + { X86::NEW_CMOVE_Fp64 , X86::CMOVE_F }, + { X86::NEW_CMOVE_Fp80 , X86::CMOVE_F }, + { X86::NEW_CMOVNBE_Fp32 , X86::CMOVNBE_F }, + { X86::NEW_CMOVNBE_Fp64 , X86::CMOVNBE_F }, + { X86::NEW_CMOVNBE_Fp80 , X86::CMOVNBE_F }, + { X86::NEW_CMOVNB_Fp32 , X86::CMOVNB_F }, + { X86::NEW_CMOVNB_Fp64 , X86::CMOVNB_F }, + { X86::NEW_CMOVNB_Fp80 , X86::CMOVNB_F }, + { X86::NEW_CMOVNE_Fp32 , X86::CMOVNE_F }, + { X86::NEW_CMOVNE_Fp64 , X86::CMOVNE_F }, + { X86::NEW_CMOVNE_Fp80 , X86::CMOVNE_F }, + { X86::NEW_CMOVNP_Fp32 , X86::CMOVNP_F }, + { X86::NEW_CMOVNP_Fp64 , X86::CMOVNP_F }, + { X86::NEW_CMOVNP_Fp80 , X86::CMOVNP_F }, + { X86::NEW_CMOVP_Fp32 , X86::CMOVP_F }, + { X86::NEW_CMOVP_Fp64 , X86::CMOVP_F }, + { X86::NEW_CMOVP_Fp80 , X86::CMOVP_F }, + { X86::SIN_Fp32 , X86::SIN_F }, { X86::SIN_Fp64 , X86::SIN_F }, { X86::SIN_Fp80 , X86::SIN_F }, Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=42285&r1=42284&r2=42285&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Sep 24 20:57:46 2007 @@ -31,6 +31,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SSARegMap.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetOptions.h" @@ -3337,41 +3338,58 @@ SDOperand AndNode = DAG.getNode(ISD::AND, MVT::i8, ShAmt, DAG.getConstant(32, MVT::i8)); SDOperand COps[]={DAG.getEntryNode(), AndNode, DAG.getConstant(0, MVT::i8)}; - SDOperand InFlag = DAG.getNode(X86ISD::CMP, VTs, 2, COps, 3).getValue(1); + SDOperand Cond = NewCCModeling + ? DAG.getNode(X86ISD::CMP_NEW, MVT::i32, + AndNode, DAG.getConstant(0, MVT::i8)) + : DAG.getNode(X86ISD::CMP, VTs, 2, COps, 3).getValue(1); SDOperand Hi, Lo; SDOperand CC = DAG.getConstant(X86::COND_NE, MVT::i8); - + unsigned Opc = NewCCModeling ? X86ISD::CMOV_NEW : X86ISD::CMOV; VTs = DAG.getNodeValueTypes(MVT::i32, MVT::Flag); SmallVector Ops; if (Op.getOpcode() == ISD::SHL_PARTS) { Ops.push_back(Tmp2); Ops.push_back(Tmp3); Ops.push_back(CC); - Ops.push_back(InFlag); - Hi = DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size()); - InFlag = Hi.getValue(1); + Ops.push_back(Cond); + if (NewCCModeling) + Hi = DAG.getNode(Opc, MVT::i32, &Ops[0], Ops.size()); + else { + Hi = DAG.getNode(Opc, VTs, 2, &Ops[0], Ops.size()); + Cond = Hi.getValue(1); + } Ops.clear(); Ops.push_back(Tmp3); Ops.push_back(Tmp1); Ops.push_back(CC); - Ops.push_back(InFlag); - Lo = DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size()); + Ops.push_back(Cond); + if (NewCCModeling) + Lo = DAG.getNode(Opc, MVT::i32, &Ops[0], Ops.size()); + else + Lo = DAG.getNode(Opc, VTs, 2, &Ops[0], Ops.size()); } else { Ops.push_back(Tmp2); Ops.push_back(Tmp3); Ops.push_back(CC); - Ops.push_back(InFlag); - Lo = DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size()); - InFlag = Lo.getValue(1); + Ops.push_back(Cond); + if (NewCCModeling) + Lo = DAG.getNode(Opc, MVT::i32, &Ops[0], Ops.size()); + else { + Lo = DAG.getNode(Opc, VTs, 2, &Ops[0], Ops.size()); + Cond = Lo.getValue(1); + } Ops.clear(); Ops.push_back(Tmp3); Ops.push_back(Tmp1); Ops.push_back(CC); - Ops.push_back(InFlag); - Hi = DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size()); + Ops.push_back(Cond); + if (NewCCModeling) + Hi = DAG.getNode(Opc, MVT::i32, &Ops[0], Ops.size()); + else + Hi = DAG.getNode(Opc, VTs, 2, &Ops[0], Ops.size()); } VTs = DAG.getNodeValueTypes(MVT::i32, MVT::i32); @@ -3668,6 +3686,43 @@ } } +SDOperand X86TargetLowering::LowerSETCC_New(SDOperand Op, SelectionDAG &DAG) { + assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer"); + SDOperand Op0 = Op.getOperand(0); + SDOperand Op1 = Op.getOperand(1); + SDOperand CC = Op.getOperand(2); + ISD::CondCode SetCCOpcode = cast(CC)->get(); + bool isFP = MVT::isFloatingPoint(Op.getOperand(1).getValueType()); + unsigned X86CC; + + SDOperand Cond = DAG.getNode(X86ISD::CMP_NEW, MVT::i32, Op0, Op1); + if (translateX86CC(cast(CC)->get(), isFP, X86CC, + Op0, Op1, DAG)) + return DAG.getNode(X86ISD::SETCC_NEW, MVT::i8, + DAG.getConstant(X86CC, MVT::i8), Cond); + + assert(isFP && "Illegal integer SetCC!"); + + switch (SetCCOpcode) { + default: assert(false && "Illegal floating point SetCC!"); + case ISD::SETOEQ: { // !PF & ZF + SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC_NEW, MVT::i8, + DAG.getConstant(X86::COND_NP, MVT::i8), Cond); + SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC_NEW, MVT::i8, + DAG.getConstant(X86::COND_E, MVT::i8), Cond); + return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2); + } + case ISD::SETUNE: { // PF | !ZF + SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC_NEW, MVT::i8, + DAG.getConstant(X86::COND_P, MVT::i8), Cond); + SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC_NEW, MVT::i8, + DAG.getConstant(X86::COND_NE, MVT::i8), Cond); + return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2); + } + } +} + + SDOperand X86TargetLowering::LowerSELECT(SDOperand Op, SelectionDAG &DAG) { bool addTest = true; SDOperand Chain = DAG.getEntryNode(); @@ -3718,6 +3773,56 @@ return DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size()); } +SDOperand X86TargetLowering::LowerSELECT_New(SDOperand Op, SelectionDAG &DAG) { + bool addTest = true; + SDOperand Cond = Op.getOperand(0); + SDOperand CC; + + if (Cond.getOpcode() == ISD::SETCC) + Cond = LowerSETCC_New(Cond, DAG); + + if (Cond.getOpcode() == X86ISD::SETCC_NEW) { + 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()); + if ((Opc == X86ISD::CMP_NEW || + Opc == X86ISD::COMI_NEW || + Opc == X86ISD::UCOMI_NEW) && + !IllegalFPCMov) { + Cond = DAG.getNode(Opc, MVT::i32, Cmp.getOperand(0), Cmp.getOperand(1)); + addTest = false; + } + } + + if (addTest) { + CC = DAG.getConstant(X86::COND_NE, MVT::i8); + Cond = DAG.getNode(X86ISD::CMP_NEW, MVT::i32, Cond, + DAG.getConstant(0, MVT::i8)); + } + + const MVT::ValueType *VTs = DAG.getNodeValueTypes(Op.getValueType(), + MVT::Flag); + SmallVector Ops; + // X86ISD::CMOV means set the result (which is operand 1) to the RHS if + // condition is true. + Ops.push_back(Op.getOperand(2)); + Ops.push_back(Op.getOperand(1)); + Ops.push_back(CC); + Ops.push_back(Cond); + return DAG.getNode(X86ISD::CMOV_NEW, VTs, 2, &Ops[0], Ops.size()); +} + SDOperand X86TargetLowering::LowerBRCOND(SDOperand Op, SelectionDAG &DAG) { bool addTest = true; SDOperand Chain = Op.getOperand(0); @@ -3756,6 +3861,43 @@ Cond, Op.getOperand(2), CC, Cond.getValue(1)); } +SDOperand X86TargetLowering::LowerBRCOND_New(SDOperand Op, SelectionDAG &DAG) { + bool addTest = true; + SDOperand Chain = Op.getOperand(0); + SDOperand Cond = Op.getOperand(1); + SDOperand Dest = Op.getOperand(2); + SDOperand CC; + + if (Cond.getOpcode() == ISD::SETCC) + Cond = LowerSETCC_New(Cond, DAG); + + if (Cond.getOpcode() == X86ISD::SETCC_NEW) { + 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_NEW || + Opc == X86ISD::COMI_NEW || + Opc == X86ISD::UCOMI_NEW) { + Cond = DAG.getNode(Opc, MVT::i32, Cmp.getOperand(0), Cmp.getOperand(1)); + addTest = false; + } + } + + if (addTest) { + CC = DAG.getConstant(X86::COND_NE, MVT::i8); + Cond= DAG.getNode(X86ISD::CMP_NEW, MVT::i32, Cond, DAG.getConstant(0, MVT::i8)); + } + return DAG.getNode(X86ISD::BRCOND_NEW, Op.getValueType(), + Chain, Op.getOperand(2), CC, Cond); +} + SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { unsigned CallingConv= cast(Op.getOperand(1))->getValue(); @@ -4355,13 +4497,21 @@ SDOperand RHS = Op.getOperand(2); translateX86CC(CC, true, X86CC, LHS, RHS, DAG); - const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::Other, MVT::Flag); - SDOperand Ops1[] = { DAG.getEntryNode(), LHS, RHS }; - SDOperand Cond = DAG.getNode(Opc, VTs, 2, Ops1, 3); - VTs = DAG.getNodeValueTypes(MVT::i8, MVT::Flag); - SDOperand Ops2[] = { DAG.getConstant(X86CC, MVT::i8), Cond }; - SDOperand SetCC = DAG.getNode(X86ISD::SETCC, VTs, 2, Ops2, 2); - return DAG.getNode(ISD::ANY_EXTEND, MVT::i32, SetCC); + if (NewCCModeling) { + Opc = (Opc == X86ISD::UCOMI) ? X86ISD::UCOMI_NEW : X86ISD::COMI_NEW; + SDOperand Cond = DAG.getNode(Opc, MVT::i32, LHS, RHS); + SDOperand SetCC = DAG.getNode(X86ISD::SETCC_NEW, MVT::i8, + DAG.getConstant(X86CC, MVT::i8), Cond); + return DAG.getNode(ISD::ANY_EXTEND, MVT::i32, SetCC); + } else { + const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::Other, MVT::Flag); + SDOperand Ops1[] = { DAG.getEntryNode(), LHS, RHS }; + SDOperand Cond = DAG.getNode(Opc, VTs, 2, Ops1, 3); + VTs = DAG.getNodeValueTypes(MVT::i8, MVT::Flag); + SDOperand Ops2[] = { DAG.getConstant(X86CC, MVT::i8), Cond }; + SDOperand SetCC = DAG.getNode(X86ISD::SETCC, VTs, 2, Ops2, 2); + return DAG.getNode(ISD::ANY_EXTEND, MVT::i32, SetCC); + } } } } @@ -4529,9 +4679,15 @@ case ISD::FABS: return LowerFABS(Op, DAG); case ISD::FNEG: return LowerFNEG(Op, DAG); case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); - case ISD::SETCC: return LowerSETCC(Op, DAG, DAG.getEntryNode()); - case ISD::SELECT: return LowerSELECT(Op, DAG); - case ISD::BRCOND: return LowerBRCOND(Op, DAG); + case ISD::SETCC: return NewCCModeling + ? LowerSETCC_New(Op, DAG) + : LowerSETCC(Op, DAG, DAG.getEntryNode()); + case ISD::SELECT: return NewCCModeling + ? LowerSELECT_New(Op, DAG) + : LowerSELECT(Op, DAG); + case ISD::BRCOND: return NewCCModeling + ? LowerBRCOND_New(Op, DAG) + : LowerBRCOND(Op, DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::CALL: return LowerCALL(Op, DAG); case ISD::RET: return LowerRET(Op, DAG); @@ -4575,11 +4731,17 @@ case X86ISD::TAILCALL: return "X86ISD::TAILCALL"; case X86ISD::RDTSC_DAG: return "X86ISD::RDTSC_DAG"; case X86ISD::CMP: return "X86ISD::CMP"; + case X86ISD::CMP_NEW: return "X86ISD::CMP_NEW"; case X86ISD::COMI: return "X86ISD::COMI"; + case X86ISD::COMI_NEW: return "X86ISD::COMI_NEW"; case X86ISD::UCOMI: return "X86ISD::UCOMI"; + case X86ISD::UCOMI_NEW: return "X86ISD::UCOMI_NEW"; case X86ISD::SETCC: return "X86ISD::SETCC"; + case X86ISD::SETCC_NEW: return "X86ISD::SETCC_NEW"; case X86ISD::CMOV: return "X86ISD::CMOV"; + case X86ISD::CMOV_NEW: return "X86ISD::CMOV_NEW"; case X86ISD::BRCOND: return "X86ISD::BRCOND"; + case X86ISD::BRCOND_NEW: return "X86ISD::BRCOND_NEW"; case X86ISD::RET_FLAG: return "X86ISD::RET_FLAG"; case X86ISD::REP_STOS: return "X86ISD::REP_STOS"; case X86ISD::REP_MOVS: return "X86ISD::REP_MOVS"; @@ -4696,7 +4858,13 @@ case X86::CMOV_FR64: case X86::CMOV_V4F32: case X86::CMOV_V2F64: - case X86::CMOV_V2I64: { + case X86::CMOV_V2I64: + + case X86::NEW_CMOV_FR32: + case X86::NEW_CMOV_FR64: + case X86::NEW_CMOV_V4F32: + case X86::NEW_CMOV_V2F64: + case X86::NEW_CMOV_V2I64: { // To "insert" a SELECT_CC instruction, we actually have to insert the // diamond control-flow pattern. The incoming instruction knows the // destination vreg to set, the condition code register to branch on, the @@ -4853,6 +5021,7 @@ switch (Opc) { default: break; case X86ISD::SETCC: + case X86ISD::SETCC_NEW: KnownZero |= (MVT::getIntVTBitMask(Op.getValueType()) ^ 1ULL); break; } Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=42285&r1=42284&r2=42285&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Sep 24 20:57:46 2007 @@ -117,22 +117,26 @@ /// X86 compare and logical compare instructions. CMP, COMI, UCOMI, + CMP_NEW, COMI_NEW, UCOMI_NEW, /// X86 SetCC. Operand 1 is condition code, and operand 2 is the flag /// operand produced by a CMP instruction. SETCC, + SETCC_NEW, /// X86 conditional moves. Operand 1 and operand 2 are the two values /// to select from (operand 1 is a R/W operand). Operand 3 is the /// condition code, and operand 4 is the flag operand produced by a CMP /// or TEST instruction. It also writes a flag result. CMOV, + CMOV_NEW, /// X86 conditional branches. Operand 1 is the chain operand, operand 2 /// is the block to branch if condition is true, operand 3 is the /// condition code, and operand 4 is the flag operand produced by a CMP /// or TEST instruction. BRCOND, + BRCOND_NEW, /// Return with a flag operand. Operand 1 is the chain operand, operand /// 2 is the number of bytes of stack to pop. @@ -422,8 +426,11 @@ SDOperand LowerFNEG(SDOperand Op, SelectionDAG &DAG); SDOperand LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG); SDOperand LowerSETCC(SDOperand Op, SelectionDAG &DAG, SDOperand Chain); + SDOperand LowerSETCC_New(SDOperand Op, SelectionDAG &DAG); SDOperand LowerSELECT(SDOperand Op, SelectionDAG &DAG); + SDOperand LowerSELECT_New(SDOperand Op, SelectionDAG &DAG); SDOperand LowerBRCOND(SDOperand Op, SelectionDAG &DAG); + SDOperand LowerBRCOND_New(SDOperand Op, SelectionDAG &DAG); SDOperand LowerMEMSET(SDOperand Op, SelectionDAG &DAG); SDOperand LowerMEMCPY(SDOperand Op, SelectionDAG &DAG); SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG); Modified: llvm/trunk/lib/Target/X86/X86InstrFPStack.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFPStack.td?rev=42285&r1=42284&r2=42285&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrFPStack.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrFPStack.td Mon Sep 24 20:57:46 2007 @@ -320,6 +320,31 @@ defm CMOVNP : FPCMov; } +multiclass NEW_FPCMov { + def _Fp32 : FpIf32<(outs RFP32:$dst), (ins RFP32:$src1, RFP32:$src2), + CondMovFP, + [(set RFP32:$dst, (X86cmov_new RFP32:$src1, RFP32:$src2, + cc, EFLAGS))]>; + def _Fp64 : FpIf64<(outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2), + CondMovFP, + [(set RFP64:$dst, (X86cmov_new RFP64:$src1, RFP64:$src2, + cc, EFLAGS))]>; + def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), + CondMovFP, + [(set RFP80:$dst, (X86cmov_new RFP80:$src1, RFP80:$src2, + cc, EFLAGS))]>; +} +let Uses = [EFLAGS], isTwoAddress = 1 in { +defm NEW_CMOVB : NEW_FPCMov; +defm NEW_CMOVBE : NEW_FPCMov; +defm NEW_CMOVE : NEW_FPCMov; +defm NEW_CMOVP : NEW_FPCMov; +defm NEW_CMOVNB : NEW_FPCMov; +defm NEW_CMOVNBE: NEW_FPCMov; +defm NEW_CMOVNE : NEW_FPCMov; +defm NEW_CMOVNP : NEW_FPCMov; +} + // These are not factored because there's no clean way to pass DA/DB. def CMOVB_F : FPI<0xC0, AddRegFrm, (outs RST:$op), (ins), "fcmovb\t{$op, %st(0)|%ST(0), $op}">, DA; Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=42285&r1=42284&r2=42285&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon Sep 24 20:57:46 2007 @@ -21,6 +21,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/SSARegMap.h" +#include "llvm/Target/TargetOptions.h" using namespace llvm; X86InstrInfo::X86InstrInfo(X86TargetMachine &tm) @@ -385,28 +386,68 @@ case X86::JNP: return X86::COND_NP; case X86::JO: return X86::COND_O; case X86::JNO: return X86::COND_NO; + // TEMPORARY + case X86::NEW_JE: return X86::COND_E; + case X86::NEW_JNE: return X86::COND_NE; + case X86::NEW_JL: return X86::COND_L; + case X86::NEW_JLE: return X86::COND_LE; + case X86::NEW_JG: return X86::COND_G; + case X86::NEW_JGE: return X86::COND_GE; + case X86::NEW_JB: return X86::COND_B; + case X86::NEW_JBE: return X86::COND_BE; + case X86::NEW_JA: return X86::COND_A; + case X86::NEW_JAE: return X86::COND_AE; + case X86::NEW_JS: return X86::COND_S; + case X86::NEW_JNS: return X86::COND_NS; + case X86::NEW_JP: return X86::COND_P; + case X86::NEW_JNP: return X86::COND_NP; + case X86::NEW_JO: return X86::COND_O; + case X86::NEW_JNO: return X86::COND_NO; + } } unsigned X86::GetCondBranchFromCond(X86::CondCode CC) { + if (!NewCCModeling) { + switch (CC) { + default: assert(0 && "Illegal condition code!"); + case X86::COND_E: return X86::JE; + case X86::COND_NE: return X86::JNE; + case X86::COND_L: return X86::JL; + case X86::COND_LE: return X86::JLE; + case X86::COND_G: return X86::JG; + case X86::COND_GE: return X86::JGE; + case X86::COND_B: return X86::JB; + case X86::COND_BE: return X86::JBE; + case X86::COND_A: return X86::JA; + case X86::COND_AE: return X86::JAE; + case X86::COND_S: return X86::JS; + case X86::COND_NS: return X86::JNS; + case X86::COND_P: return X86::JP; + case X86::COND_NP: return X86::JNP; + case X86::COND_O: return X86::JO; + case X86::COND_NO: return X86::JNO; + } + } + switch (CC) { default: assert(0 && "Illegal condition code!"); - case X86::COND_E: return X86::JE; - case X86::COND_NE: return X86::JNE; - case X86::COND_L: return X86::JL; - case X86::COND_LE: return X86::JLE; - case X86::COND_G: return X86::JG; - case X86::COND_GE: return X86::JGE; - case X86::COND_B: return X86::JB; - case X86::COND_BE: return X86::JBE; - case X86::COND_A: return X86::JA; - case X86::COND_AE: return X86::JAE; - case X86::COND_S: return X86::JS; - case X86::COND_NS: return X86::JNS; - case X86::COND_P: return X86::JP; - case X86::COND_NP: return X86::JNP; - case X86::COND_O: return X86::JO; - case X86::COND_NO: return X86::JNO; + case X86::COND_E: return X86::NEW_JE; + case X86::COND_NE: return X86::NEW_JNE; + case X86::COND_L: return X86::NEW_JL; + case X86::COND_LE: return X86::NEW_JLE; + case X86::COND_G: return X86::NEW_JG; + case X86::COND_GE: return X86::NEW_JGE; + case X86::COND_B: return X86::NEW_JB; + case X86::COND_BE: return X86::NEW_JBE; + case X86::COND_A: return X86::NEW_JA; + case X86::COND_AE: return X86::NEW_JAE; + case X86::COND_S: return X86::NEW_JS; + case X86::COND_NS: return X86::NEW_JNS; + case X86::COND_P: return X86::NEW_JP; + case X86::COND_NP: return X86::NEW_JNP; + case X86::COND_O: return X86::NEW_JO; + case X86::COND_NO: return X86::NEW_JNO; } } Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=42285&r1=42284&r2=42285&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon Sep 24 20:57:46 2007 @@ -26,12 +26,21 @@ def SDTX86Cmov : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>; +def SDTX86Cmov_NEW : SDTypeProfile<1, 4, + [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, + SDTCisVT<3, i8>, SDTCisVT<4, i32>]>; def SDTX86BrCond : SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i8>]>; +def SDTX86BrCond_NEW : SDTypeProfile<0, 3, + [SDTCisVT<0, OtherVT>, + SDTCisVT<1, i8>, SDTCisVT<2, i32>]>; def SDTX86SetCC : SDTypeProfile<1, 1, [SDTCisVT<0, i8>, SDTCisVT<1, i8>]>; +def SDTX86SetCC_NEW : SDTypeProfile<1, 2, + [SDTCisVT<0, i8>, + SDTCisVT<1, i8>, SDTCisVT<2, i32>]>; def SDTX86Ret : SDTypeProfile<0, 1, [SDTCisVT<0, i16>]>; @@ -58,13 +67,18 @@ def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest, [SDNPHasChain, SDNPOutFlag]>; +def X86cmp_new : SDNode<"X86ISD::CMP_NEW" , SDTX86CmpTest>; -def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov, +def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov, [SDNPInFlag, SDNPOutFlag]>; +def X86cmov_new: SDNode<"X86ISD::CMOV_NEW", SDTX86Cmov_NEW>; def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond, [SDNPHasChain, SDNPInFlag]>; +def X86brcond_new : SDNode<"X86ISD::BRCOND_NEW", SDTX86BrCond_NEW, + [SDNPHasChain]>; def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC, [SDNPInFlag, SDNPOutFlag]>; +def X86setcc_new : SDNode<"X86ISD::SETCC_NEW", SDTX86SetCC_NEW>; def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret, [SDNPHasChain, SDNPOptInFlag]>; @@ -301,6 +315,7 @@ } // Conditional branches +let Uses = [EFLAGS] in { def JE : IBr<0x84, (ins brtarget:$dst), "je\t$dst", [(X86brcond bb:$dst, X86_COND_E)]>, TB; def JNE : IBr<0x85, (ins brtarget:$dst), "jne\t$dst", @@ -335,6 +350,44 @@ [(X86brcond bb:$dst, X86_COND_O)]>, TB; def JNO : IBr<0x81, (ins brtarget:$dst), "jno\t$dst", [(X86brcond bb:$dst, X86_COND_NO)]>, TB; +} // Uses = [EFLAGS] + +let Uses = [EFLAGS] in { +def NEW_JE : IBr<0x84, (ins brtarget:$dst), "je\t$dst", + [(X86brcond_new bb:$dst, X86_COND_E, EFLAGS)]>, TB; +def NEW_JNE : IBr<0x85, (ins brtarget:$dst), "jne\t$dst", + [(X86brcond_new bb:$dst, X86_COND_NE, EFLAGS)]>, TB; +def NEW_JL : IBr<0x8C, (ins brtarget:$dst), "jl\t$dst", + [(X86brcond_new bb:$dst, X86_COND_L, EFLAGS)]>, TB; +def NEW_JLE : IBr<0x8E, (ins brtarget:$dst), "jle\t$dst", + [(X86brcond_new bb:$dst, X86_COND_LE, EFLAGS)]>, TB; +def NEW_JG : IBr<0x8F, (ins brtarget:$dst), "jg\t$dst", + [(X86brcond_new bb:$dst, X86_COND_G, EFLAGS)]>, TB; +def NEW_JGE : IBr<0x8D, (ins brtarget:$dst), "jge\t$dst", + [(X86brcond_new bb:$dst, X86_COND_GE, EFLAGS)]>, TB; + +def NEW_JB : IBr<0x82, (ins brtarget:$dst), "jb\t$dst", + [(X86brcond_new bb:$dst, X86_COND_B, EFLAGS)]>, TB; +def NEW_JBE : IBr<0x86, (ins brtarget:$dst), "jbe\t$dst", + [(X86brcond_new bb:$dst, X86_COND_BE, EFLAGS)]>, TB; +def NEW_JA : IBr<0x87, (ins brtarget:$dst), "ja\t$dst", + [(X86brcond_new bb:$dst, X86_COND_A, EFLAGS)]>, TB; +def NEW_JAE : IBr<0x83, (ins brtarget:$dst), "jae\t$dst", + [(X86brcond_new bb:$dst, X86_COND_AE, EFLAGS)]>, TB; + +def NEW_JS : IBr<0x88, (ins brtarget:$dst), "js\t$dst", + [(X86brcond_new bb:$dst, X86_COND_S, EFLAGS)]>, TB; +def NEW_JNS : IBr<0x89, (ins brtarget:$dst), "jns\t$dst", + [(X86brcond_new bb:$dst, X86_COND_NS, EFLAGS)]>, TB; +def NEW_JP : IBr<0x8A, (ins brtarget:$dst), "jp\t$dst", + [(X86brcond_new bb:$dst, X86_COND_P, EFLAGS)]>, TB; +def NEW_JNP : IBr<0x8B, (ins brtarget:$dst), "jnp\t$dst", + [(X86brcond_new bb:$dst, X86_COND_NP, EFLAGS)]>, TB; +def NEW_JO : IBr<0x80, (ins brtarget:$dst), "jo\t$dst", + [(X86brcond_new bb:$dst, X86_COND_O, EFLAGS)]>, TB; +def NEW_JNO : IBr<0x81, (ins brtarget:$dst), "jno\t$dst", + [(X86brcond_new bb:$dst, X86_COND_NO, EFLAGS)]>, TB; +} // Uses = [EFLAGS] //===----------------------------------------------------------------------===// // Call Instructions... @@ -343,7 +396,7 @@ // All calls clobber the non-callee saved registers... let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, - XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7] in { + XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, EFLAGS] in { def CALLpcrel32 : I<0xE8, RawFrm, (outs), (ins i32imm:$dst, variable_ops), "call\t${dst:call}", []>; def CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst, variable_ops), @@ -640,6 +693,7 @@ let isTwoAddress = 1 in { // Conditional moves +let Uses = [EFLAGS] in { def CMOVB16rr : I<0x42, MRMSrcReg, // if , + TB, OpSize; +def NEW_CMOVB16rm : I<0x42, MRMSrcMem, // if , + TB, OpSize; +def NEW_CMOVB32rr : I<0x42, MRMSrcReg, // if , + TB; +def NEW_CMOVB32rm : I<0x42, MRMSrcMem, // if , + TB; + +def NEW_CMOVAE16rr: I<0x43, MRMSrcReg, // if >=u, GR16 = GR16 + (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), + "cmovae\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, GR16:$src2, + X86_COND_AE, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVAE16rm: I<0x43, MRMSrcMem, // if >=u, GR16 = [mem16] + (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), + "cmovae\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, (loadi16 addr:$src2), + X86_COND_AE, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVAE32rr: I<0x43, MRMSrcReg, // if >=u, GR32 = GR32 + (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), + "cmovae\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, GR32:$src2, + X86_COND_AE, EFLAGS))]>, + TB; +def NEW_CMOVAE32rm: I<0x43, MRMSrcMem, // if >=u, GR32 = [mem32] + (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), + "cmovae\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, (loadi32 addr:$src2), + X86_COND_AE, EFLAGS))]>, + TB; + +def NEW_CMOVE16rr : I<0x44, MRMSrcReg, // if ==, GR16 = GR16 + (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), + "cmove\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, GR16:$src2, + X86_COND_E, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVE16rm : I<0x44, MRMSrcMem, // if ==, GR16 = [mem16] + (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), + "cmove\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, (loadi16 addr:$src2), + X86_COND_E, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVE32rr : I<0x44, MRMSrcReg, // if ==, GR32 = GR32 + (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), + "cmove\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, GR32:$src2, + X86_COND_E, EFLAGS))]>, + TB; +def NEW_CMOVE32rm : I<0x44, MRMSrcMem, // if ==, GR32 = [mem32] + (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), + "cmove\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, (loadi32 addr:$src2), + X86_COND_E, EFLAGS))]>, + TB; + +def NEW_CMOVNE16rr: I<0x45, MRMSrcReg, // if !=, GR16 = GR16 + (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), + "cmovne\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, GR16:$src2, + X86_COND_NE, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVNE16rm: I<0x45, MRMSrcMem, // if !=, GR16 = [mem16] + (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), + "cmovne\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, (loadi16 addr:$src2), + X86_COND_NE, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVNE32rr: I<0x45, MRMSrcReg, // if !=, GR32 = GR32 + (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), + "cmovne\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, GR32:$src2, + X86_COND_NE, EFLAGS))]>, + TB; +def NEW_CMOVNE32rm: I<0x45, MRMSrcMem, // if !=, GR32 = [mem32] + (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), + "cmovne\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, (loadi32 addr:$src2), + X86_COND_NE, EFLAGS))]>, + TB; + +def NEW_CMOVBE16rr: I<0x46, MRMSrcReg, // if <=u, GR16 = GR16 + (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), + "cmovbe\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, GR16:$src2, + X86_COND_BE, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVBE16rm: I<0x46, MRMSrcMem, // if <=u, GR16 = [mem16] + (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), + "cmovbe\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, (loadi16 addr:$src2), + X86_COND_BE, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVBE32rr: I<0x46, MRMSrcReg, // if <=u, GR32 = GR32 + (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), + "cmovbe\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, GR32:$src2, + X86_COND_BE, EFLAGS))]>, + TB; +def NEW_CMOVBE32rm: I<0x46, MRMSrcMem, // if <=u, GR32 = [mem32] + (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), + "cmovbe\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, (loadi32 addr:$src2), + X86_COND_BE, EFLAGS))]>, + TB; + +def NEW_CMOVA16rr : I<0x47, MRMSrcReg, // if >u, GR16 = GR16 + (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), + "cmova\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, GR16:$src2, + X86_COND_A, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVA16rm : I<0x47, MRMSrcMem, // if >u, GR16 = [mem16] + (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), + "cmova\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, (loadi16 addr:$src2), + X86_COND_A, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVA32rr : I<0x47, MRMSrcReg, // if >u, GR32 = GR32 + (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), + "cmova\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, GR32:$src2, + X86_COND_A, EFLAGS))]>, + TB; +def NEW_CMOVA32rm : I<0x47, MRMSrcMem, // if >u, GR32 = [mem32] + (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), + "cmova\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, (loadi32 addr:$src2), + X86_COND_A, EFLAGS))]>, + TB; + +def NEW_CMOVL16rr : I<0x4C, MRMSrcReg, // if , + TB, OpSize; +def NEW_CMOVL16rm : I<0x4C, MRMSrcMem, // if , + TB, OpSize; +def NEW_CMOVL32rr : I<0x4C, MRMSrcReg, // if , + TB; +def NEW_CMOVL32rm : I<0x4C, MRMSrcMem, // if , + TB; + +def NEW_CMOVGE16rr: I<0x4D, MRMSrcReg, // if >=s, GR16 = GR16 + (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), + "cmovge\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, GR16:$src2, + X86_COND_GE, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVGE16rm: I<0x4D, MRMSrcMem, // if >=s, GR16 = [mem16] + (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), + "cmovge\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, (loadi16 addr:$src2), + X86_COND_GE, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVGE32rr: I<0x4D, MRMSrcReg, // if >=s, GR32 = GR32 + (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), + "cmovge\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, GR32:$src2, + X86_COND_GE, EFLAGS))]>, + TB; +def NEW_CMOVGE32rm: I<0x4D, MRMSrcMem, // if >=s, GR32 = [mem32] + (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), + "cmovge\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, (loadi32 addr:$src2), + X86_COND_GE, EFLAGS))]>, + TB; + +def NEW_CMOVLE16rr: I<0x4E, MRMSrcReg, // if <=s, GR16 = GR16 + (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), + "cmovle\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, GR16:$src2, + X86_COND_LE, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVLE16rm: I<0x4E, MRMSrcMem, // if <=s, GR16 = [mem16] + (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), + "cmovle\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, (loadi16 addr:$src2), + X86_COND_LE, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVLE32rr: I<0x4E, MRMSrcReg, // if <=s, GR32 = GR32 + (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), + "cmovle\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, GR32:$src2, + X86_COND_LE, EFLAGS))]>, + TB; +def NEW_CMOVLE32rm: I<0x4E, MRMSrcMem, // if <=s, GR32 = [mem32] + (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), + "cmovle\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, (loadi32 addr:$src2), + X86_COND_LE, EFLAGS))]>, + TB; + +def NEW_CMOVG16rr : I<0x4F, MRMSrcReg, // if >s, GR16 = GR16 + (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), + "cmovg\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, GR16:$src2, + X86_COND_G, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVG16rm : I<0x4F, MRMSrcMem, // if >s, GR16 = [mem16] + (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), + "cmovg\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, (loadi16 addr:$src2), + X86_COND_G, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVG32rr : I<0x4F, MRMSrcReg, // if >s, GR32 = GR32 + (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), + "cmovg\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, GR32:$src2, + X86_COND_G, EFLAGS))]>, + TB; +def NEW_CMOVG32rm : I<0x4F, MRMSrcMem, // if >s, GR32 = [mem32] + (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), + "cmovg\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, (loadi32 addr:$src2), + X86_COND_G, EFLAGS))]>, + TB; + +def NEW_CMOVS16rr : I<0x48, MRMSrcReg, // if signed, GR16 = GR16 + (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), + "cmovs\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, GR16:$src2, + X86_COND_S, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVS16rm : I<0x48, MRMSrcMem, // if signed, GR16 = [mem16] + (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), + "cmovs\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, (loadi16 addr:$src2), + X86_COND_S, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVS32rr : I<0x48, MRMSrcReg, // if signed, GR32 = GR32 + (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), + "cmovs\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, GR32:$src2, + X86_COND_S, EFLAGS))]>, + TB; +def NEW_CMOVS32rm : I<0x48, MRMSrcMem, // if signed, GR32 = [mem32] + (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), + "cmovs\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, (loadi32 addr:$src2), + X86_COND_S, EFLAGS))]>, + TB; + +def NEW_CMOVNS16rr: I<0x49, MRMSrcReg, // if !signed, GR16 = GR16 + (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), + "cmovns\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, GR16:$src2, + X86_COND_NS, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVNS16rm: I<0x49, MRMSrcMem, // if !signed, GR16 = [mem16] + (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), + "cmovns\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, (loadi16 addr:$src2), + X86_COND_NS, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVNS32rr: I<0x49, MRMSrcReg, // if !signed, GR32 = GR32 + (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), + "cmovns\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, GR32:$src2, + X86_COND_NS, EFLAGS))]>, + TB; +def NEW_CMOVNS32rm: I<0x49, MRMSrcMem, // if !signed, GR32 = [mem32] + (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), + "cmovns\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, (loadi32 addr:$src2), + X86_COND_NS, EFLAGS))]>, + TB; + +def NEW_CMOVP16rr : I<0x4A, MRMSrcReg, // if parity, GR16 = GR16 + (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), + "cmovp\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, GR16:$src2, + X86_COND_P, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVP16rm : I<0x4A, MRMSrcMem, // if parity, GR16 = [mem16] + (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), + "cmovp\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, (loadi16 addr:$src2), + X86_COND_P, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVP32rr : I<0x4A, MRMSrcReg, // if parity, GR32 = GR32 + (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), + "cmovp\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, GR32:$src2, + X86_COND_P, EFLAGS))]>, + TB; +def NEW_CMOVP32rm : I<0x4A, MRMSrcMem, // if parity, GR32 = [mem32] + (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), + "cmovp\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, (loadi32 addr:$src2), + X86_COND_P, EFLAGS))]>, + TB; + +def NEW_CMOVNP16rr : I<0x4B, MRMSrcReg, // if !parity, GR16 = GR16 + (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), + "cmovnp\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, GR16:$src2, + X86_COND_NP, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVNP16rm : I<0x4B, MRMSrcMem, // if !parity, GR16 = [mem16] + (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), + "cmovnp\t{$src2, $dst|$dst, $src2}", + [(set GR16:$dst, (X86cmov_new GR16:$src1, (loadi16 addr:$src2), + X86_COND_NP, EFLAGS))]>, + TB, OpSize; +def NEW_CMOVNP32rr : I<0x4B, MRMSrcReg, // if !parity, GR32 = GR32 + (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), + "cmovnp\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, GR32:$src2, + X86_COND_NP, EFLAGS))]>, + TB; +def NEW_CMOVNP32rm : I<0x4B, MRMSrcMem, // if !parity, GR32 = [mem32] + (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), + "cmovnp\t{$src2, $dst|$dst, $src2}", + [(set GR32:$dst, (X86cmov_new GR32:$src1, (loadi32 addr:$src2), + X86_COND_NP, EFLAGS))]>, + TB; +} // Uses = [EFLAGS] + + // unary instructions let CodeSize = 2 in { let Defs = [EFLAGS] in { @@ -2028,7 +2434,7 @@ //===----------------------------------------------------------------------===// // Test instructions are just like AND, except they don't generate a result. // - let Defs = [EFLAGS] in { +let Defs = [EFLAGS] in { let isCommutable = 1 in { // TEST X, Y --> TEST Y, X def TEST8rr : I<0x84, MRMDestReg, (outs), (ins GR8:$src1, GR8:$src2), "test{b}\t{$src2, $src1|$src1, $src2}", @@ -2081,12 +2487,77 @@ } // Defs = [EFLAGS] +let Defs = [EFLAGS] in { +let isCommutable = 1 in { // TEST X, Y --> TEST Y, X +def NEW_TEST8rr : I<0x84, MRMDestReg, (outs), (ins GR8:$src1, GR8:$src2), + "test{b}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and GR8:$src1, GR8:$src2), 0), + (implicit EFLAGS)]>; +def NEW_TEST16rr : I<0x85, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2), + "test{w}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and GR16:$src1, GR16:$src2), 0), + (implicit EFLAGS)]>, + OpSize; +def NEW_TEST32rr : I<0x85, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2), + "test{l}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and GR32:$src1, GR32:$src2), 0), + (implicit EFLAGS)]>; +} + +def NEW_TEST8rm : I<0x84, MRMSrcMem, (outs), (ins GR8 :$src1, i8mem :$src2), + "test{b}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and GR8:$src1, (loadi8 addr:$src2)), 0), + (implicit EFLAGS)]>; +def NEW_TEST16rm : I<0x85, MRMSrcMem, (outs), (ins GR16:$src1, i16mem:$src2), + "test{w}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and GR16:$src1, (loadi16 addr:$src2)), 0), + (implicit EFLAGS)]>, OpSize; +def NEW_TEST32rm : I<0x85, MRMSrcMem, (outs), (ins GR32:$src1, i32mem:$src2), + "test{l}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and GR32:$src1, (loadi32 addr:$src2)), 0), + (implicit EFLAGS)]>; + +def NEW_TEST8ri : Ii8 <0xF6, MRM0r, // flags = GR8 & imm8 + (outs), (ins GR8:$src1, i8imm:$src2), + "test{b}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and GR8:$src1, imm:$src2), 0), + (implicit EFLAGS)]>; +def NEW_TEST16ri : Ii16<0xF7, MRM0r, // flags = GR16 & imm16 + (outs), (ins GR16:$src1, i16imm:$src2), + "test{w}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and GR16:$src1, imm:$src2), 0), + (implicit EFLAGS)]>, OpSize; +def NEW_TEST32ri : Ii32<0xF7, MRM0r, // flags = GR32 & imm32 + (outs), (ins GR32:$src1, i32imm:$src2), + "test{l}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and GR32:$src1, imm:$src2), 0), + (implicit EFLAGS)]>; + +def NEW_TEST8mi : Ii8 <0xF6, MRM0m, // flags = [mem8] & imm8 + (outs), (ins i8mem:$src1, i8imm:$src2), + "test{b}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and (loadi8 addr:$src1), imm:$src2), 0), + (implicit EFLAGS)]>; +def NEW_TEST16mi : Ii16<0xF7, MRM0m, // flags = [mem16] & imm16 + (outs), (ins i16mem:$src1, i16imm:$src2), + "test{w}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and (loadi16 addr:$src1), imm:$src2), 0), + (implicit EFLAGS)]>, OpSize; +def NEW_TEST32mi : Ii32<0xF7, MRM0m, // flags = [mem32] & imm32 + (outs), (ins i32mem:$src1, i32imm:$src2), + "test{l}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and (loadi32 addr:$src1), imm:$src2), 0), + (implicit EFLAGS)]>; +} // Defs = [EFLAGS] + + // Condition code ops, incl. set if equal/not equal/... let Defs = [EFLAGS], Uses = [AH] in def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf", []>; // flags = AH let Defs = [AH], Uses = [EFLAGS] in def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", []>; // AH = flags +let Uses = [EFLAGS] in { def SETEr : I<0x94, MRM0r, (outs GR8 :$dst), (ins), "sete\t$dst", @@ -2229,6 +2700,155 @@ "setnp\t$dst", [(store (X86setcc X86_COND_NP), addr:$dst)]>, TB; // [mem8] = not parity +} // Uses = [EFLAGS] + +let Uses = [EFLAGS] in { +def NEW_SETEr : I<0x94, MRM0r, + (outs GR8 :$dst), (ins), + "sete\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_E, EFLAGS))]>, + TB; // GR8 = == +def NEW_SETEm : I<0x94, MRM0m, + (outs), (ins i8mem:$dst), + "sete\t$dst", + [(store (X86setcc_new X86_COND_E, EFLAGS), addr:$dst)]>, + TB; // [mem8] = == +def NEW_SETNEr : I<0x95, MRM0r, + (outs GR8 :$dst), (ins), + "setne\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_NE, EFLAGS))]>, + TB; // GR8 = != +def NEW_SETNEm : I<0x95, MRM0m, + (outs), (ins i8mem:$dst), + "setne\t$dst", + [(store (X86setcc_new X86_COND_NE, EFLAGS), addr:$dst)]>, + TB; // [mem8] = != +def NEW_SETLr : I<0x9C, MRM0r, + (outs GR8 :$dst), (ins), + "setl\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_L, EFLAGS))]>, + TB; // GR8 = < signed +def NEW_SETLm : I<0x9C, MRM0m, + (outs), (ins i8mem:$dst), + "setl\t$dst", + [(store (X86setcc_new X86_COND_L, EFLAGS), addr:$dst)]>, + TB; // [mem8] = < signed +def NEW_SETGEr : I<0x9D, MRM0r, + (outs GR8 :$dst), (ins), + "setge\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_GE, EFLAGS))]>, + TB; // GR8 = >= signed +def NEW_SETGEm : I<0x9D, MRM0m, + (outs), (ins i8mem:$dst), + "setge\t$dst", + [(store (X86setcc_new X86_COND_GE, EFLAGS), addr:$dst)]>, + TB; // [mem8] = >= signed +def NEW_SETLEr : I<0x9E, MRM0r, + (outs GR8 :$dst), (ins), + "setle\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_LE, EFLAGS))]>, + TB; // GR8 = <= signed +def NEW_SETLEm : I<0x9E, MRM0m, + (outs), (ins i8mem:$dst), + "setle\t$dst", + [(store (X86setcc_new X86_COND_LE, EFLAGS), addr:$dst)]>, + TB; // [mem8] = <= signed +def NEW_SETGr : I<0x9F, MRM0r, + (outs GR8 :$dst), (ins), + "setg\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_G, EFLAGS))]>, + TB; // GR8 = > signed +def NEW_SETGm : I<0x9F, MRM0m, + (outs), (ins i8mem:$dst), + "setg\t$dst", + [(store (X86setcc_new X86_COND_G, EFLAGS), addr:$dst)]>, + TB; // [mem8] = > signed + +def NEW_SETBr : I<0x92, MRM0r, + (outs GR8 :$dst), (ins), + "setb\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_B, EFLAGS))]>, + TB; // GR8 = < unsign +def NEW_SETBm : I<0x92, MRM0m, + (outs), (ins i8mem:$dst), + "setb\t$dst", + [(store (X86setcc_new X86_COND_B, EFLAGS), addr:$dst)]>, + TB; // [mem8] = < unsign +def NEW_SETAEr : I<0x93, MRM0r, + (outs GR8 :$dst), (ins), + "setae\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_AE, EFLAGS))]>, + TB; // GR8 = >= unsign +def NEW_SETAEm : I<0x93, MRM0m, + (outs), (ins i8mem:$dst), + "setae\t$dst", + [(store (X86setcc_new X86_COND_AE, EFLAGS), addr:$dst)]>, + TB; // [mem8] = >= unsign +def NEW_SETBEr : I<0x96, MRM0r, + (outs GR8 :$dst), (ins), + "setbe\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_BE, EFLAGS))]>, + TB; // GR8 = <= unsign +def NEW_SETBEm : I<0x96, MRM0m, + (outs), (ins i8mem:$dst), + "setbe\t$dst", + [(store (X86setcc_new X86_COND_BE, EFLAGS), addr:$dst)]>, + TB; // [mem8] = <= unsign +def NEW_SETAr : I<0x97, MRM0r, + (outs GR8 :$dst), (ins), + "seta\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_A, EFLAGS))]>, + TB; // GR8 = > signed +def NEW_SETAm : I<0x97, MRM0m, + (outs), (ins i8mem:$dst), + "seta\t$dst", + [(store (X86setcc_new X86_COND_A, EFLAGS), addr:$dst)]>, + TB; // [mem8] = > signed + +def NEW_SETSr : I<0x98, MRM0r, + (outs GR8 :$dst), (ins), + "sets\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_S, EFLAGS))]>, + TB; // GR8 = +def NEW_SETSm : I<0x98, MRM0m, + (outs), (ins i8mem:$dst), + "sets\t$dst", + [(store (X86setcc_new X86_COND_S, EFLAGS), addr:$dst)]>, + TB; // [mem8] = +def NEW_SETNSr : I<0x99, MRM0r, + (outs GR8 :$dst), (ins), + "setns\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_NS, EFLAGS))]>, + TB; // GR8 = ! +def NEW_SETNSm : I<0x99, MRM0m, + (outs), (ins i8mem:$dst), + "setns\t$dst", + [(store (X86setcc_new X86_COND_NS, EFLAGS), addr:$dst)]>, + TB; // [mem8] = ! +def NEW_SETPr : I<0x9A, MRM0r, + (outs GR8 :$dst), (ins), + "setp\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_P, EFLAGS))]>, + TB; // GR8 = parity +def NEW_SETPm : I<0x9A, MRM0m, + (outs), (ins i8mem:$dst), + "setp\t$dst", + [(store (X86setcc_new X86_COND_P, EFLAGS), addr:$dst)]>, + TB; // [mem8] = parity +def NEW_SETNPr : I<0x9B, MRM0r, + (outs GR8 :$dst), (ins), + "setnp\t$dst", + [(set GR8:$dst, (X86setcc_new X86_COND_NP, EFLAGS))]>, + TB; // GR8 = not parity +def NEW_SETNPm : I<0x9B, MRM0m, + (outs), (ins i8mem:$dst), + "setnp\t$dst", + [(store (X86setcc_new X86_COND_NP, EFLAGS), addr:$dst)]>, + TB; // [mem8] = not parity +} // Uses = [EFLAGS] + + +//def : Pat<(X86setcc_new X86_COND_E, EFLAGS), (SETEr)>; // Integer comparisons let Defs = [EFLAGS] in { @@ -2310,6 +2930,99 @@ [(X86cmp GR32:$src1, i32immSExt8:$src2)]>; } // Defs = [EFLAGS] +let Defs = [EFLAGS] in { +def NEW_CMP8rr : I<0x38, MRMDestReg, + (outs), (ins GR8 :$src1, GR8 :$src2), + "cmp{b}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR8:$src1, GR8:$src2), (implicit EFLAGS)]>; +def NEW_CMP16rr : I<0x39, MRMDestReg, + (outs), (ins GR16:$src1, GR16:$src2), + "cmp{w}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR16:$src1, GR16:$src2), (implicit EFLAGS)]>, OpSize; +def NEW_CMP32rr : I<0x39, MRMDestReg, + (outs), (ins GR32:$src1, GR32:$src2), + "cmp{l}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR32:$src1, GR32:$src2), (implicit EFLAGS)]>; +def NEW_CMP8mr : I<0x38, MRMDestMem, + (outs), (ins i8mem :$src1, GR8 :$src2), + "cmp{b}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (loadi8 addr:$src1), GR8:$src2), + (implicit EFLAGS)]>; +def NEW_CMP16mr : I<0x39, MRMDestMem, + (outs), (ins i16mem:$src1, GR16:$src2), + "cmp{w}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (loadi16 addr:$src1), GR16:$src2), + (implicit EFLAGS)]>, OpSize; +def NEW_CMP32mr : I<0x39, MRMDestMem, + (outs), (ins i32mem:$src1, GR32:$src2), + "cmp{l}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (loadi32 addr:$src1), GR32:$src2), + (implicit EFLAGS)]>; +def NEW_CMP8rm : I<0x3A, MRMSrcMem, + (outs), (ins GR8 :$src1, i8mem :$src2), + "cmp{b}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR8:$src1, (loadi8 addr:$src2)), + (implicit EFLAGS)]>; +def NEW_CMP16rm : I<0x3B, MRMSrcMem, + (outs), (ins GR16:$src1, i16mem:$src2), + "cmp{w}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR16:$src1, (loadi16 addr:$src2)), + (implicit EFLAGS)]>, OpSize; +def NEW_CMP32rm : I<0x3B, MRMSrcMem, + (outs), (ins GR32:$src1, i32mem:$src2), + "cmp{l}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR32:$src1, (loadi32 addr:$src2)), + (implicit EFLAGS)]>; +def NEW_CMP8ri : Ii8<0x80, MRM7r, + (outs), (ins GR8:$src1, i8imm:$src2), + "cmp{b}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR8:$src1, imm:$src2), (implicit EFLAGS)]>; +def NEW_CMP16ri : Ii16<0x81, MRM7r, + (outs), (ins GR16:$src1, i16imm:$src2), + "cmp{w}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR16:$src1, imm:$src2), + (implicit EFLAGS)]>, OpSize; +def NEW_CMP32ri : Ii32<0x81, MRM7r, + (outs), (ins GR32:$src1, i32imm:$src2), + "cmp{l}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR32:$src1, imm:$src2), (implicit EFLAGS)]>; +def NEW_CMP8mi : Ii8 <0x80, MRM7m, + (outs), (ins i8mem :$src1, i8imm :$src2), + "cmp{b}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (loadi8 addr:$src1), imm:$src2), + (implicit EFLAGS)]>; +def NEW_CMP16mi : Ii16<0x81, MRM7m, + (outs), (ins i16mem:$src1, i16imm:$src2), + "cmp{w}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (loadi16 addr:$src1), imm:$src2), + (implicit EFLAGS)]>, OpSize; +def NEW_CMP32mi : Ii32<0x81, MRM7m, + (outs), (ins i32mem:$src1, i32imm:$src2), + "cmp{l}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (loadi32 addr:$src1), imm:$src2), + (implicit EFLAGS)]>; +def NEW_CMP16ri8 : Ii8<0x83, MRM7r, + (outs), (ins GR16:$src1, i16i8imm:$src2), + "cmp{w}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR16:$src1, i16immSExt8:$src2), + (implicit EFLAGS)]>, OpSize; +def NEW_CMP16mi8 : Ii8<0x83, MRM7m, + (outs), (ins i16mem:$src1, i16i8imm:$src2), + "cmp{w}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (loadi16 addr:$src1), i16immSExt8:$src2), + (implicit EFLAGS)]>, OpSize; +def NEW_CMP32mi8 : Ii8<0x83, MRM7m, + (outs), (ins i32mem:$src1, i32i8imm:$src2), + "cmp{l}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (loadi32 addr:$src1), i32immSExt8:$src2), + (implicit EFLAGS)]>; +def NEW_CMP32ri8 : Ii8<0x83, MRM7r, + (outs), (ins GR32:$src1, i32i8imm:$src2), + "cmp{l}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR32:$src1, i32immSExt8:$src2), + (implicit EFLAGS)]>; +} // Defs = [EFLAGS] + // Sign/Zero extenders def MOVSX16rr8 : I<0xBE, MRMSrcReg, (outs GR16:$dst), (ins GR8 :$src), "movs{bw|x}\t{$src, $dst|$dst, $src}", @@ -2522,6 +3235,13 @@ def : Pat<(X86cmp GR32:$src1, 0), (TEST32rr GR32:$src1, GR32:$src1)>; +def : Pat<(parallel (X86cmp_new GR8:$src1, 0), (implicit EFLAGS)), + (NEW_TEST8rr GR8:$src1, GR8:$src1)>; +def : Pat<(parallel (X86cmp_new GR16:$src1, 0), (implicit EFLAGS)), + (NEW_TEST16rr GR16:$src1, GR16:$src1)>; +def : Pat<(parallel (X86cmp_new GR32:$src1, 0), (implicit EFLAGS)), + (NEW_TEST32rr GR32:$src1, GR32:$src1)>; + // {s|z}extload bool -> {s|z}extload byte def : Pat<(sextloadi16i1 addr:$src), (MOVSX16rm8 addr:$src)>; def : Pat<(sextloadi32i1 addr:$src), (MOVSX32rm8 addr:$src)>; Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=42285&r1=42284&r2=42285&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Mon Sep 24 20:57:46 2007 @@ -36,6 +36,9 @@ [SDNPHasChain, SDNPOutFlag]>; def X86ucomi : SDNode<"X86ISD::UCOMI", SDTX86CmpTest, [SDNPHasChain, SDNPOutFlag]>; +def X86comi_new: SDNode<"X86ISD::COMI_NEW", SDTX86CmpTest, + [SDNPHasChain]>; +def X86ucomi_new: SDNode<"X86ISD::UCOMI_NEW",SDTX86CmpTest>; def X86s2vec : SDNode<"X86ISD::S2VEC", SDTypeProfile<1, 1, []>, []>; def X86pextrw : SDNode<"X86ISD::PEXTRW", SDTypeProfile<1, 2, []>, []>; def X86pinsrw : SDNode<"X86ISD::PINSRW", SDTypeProfile<1, 3, []>, []>; @@ -263,7 +266,8 @@ // CMOV* - Used to implement the SSE SELECT DAG operation. Expanded by the // scheduler into a branch sequence. -let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. +// These are expanded by the scheduler. +let Uses = [EFLAGS], usesCustomDAGSchedInserter = 1 in { def CMOV_FR32 : I<0, Pseudo, (outs FR32:$dst), (ins FR32:$t, FR32:$f, i8imm:$cond), "#CMOV_FR32 PSEUDO!", @@ -287,6 +291,35 @@ "#CMOV_V2I64 PSEUDO!", [(set VR128:$dst, (v2i64 (X86cmov VR128:$t, VR128:$f, imm:$cond)))]>; + + def NEW_CMOV_FR32 : I<0, Pseudo, + (outs FR32:$dst), (ins FR32:$t, FR32:$f, i8imm:$cond), + "#CMOV_FR32 PSEUDO!", + [(set FR32:$dst, (X86cmov_new FR32:$t, FR32:$f, imm:$cond, + EFLAGS))]>; + def NEW_CMOV_FR64 : I<0, Pseudo, + (outs FR64:$dst), (ins FR64:$t, FR64:$f, i8imm:$cond), + "#CMOV_FR64 PSEUDO!", + [(set FR64:$dst, (X86cmov_new FR64:$t, FR64:$f, imm:$cond, + EFLAGS))]>; + def NEW_CMOV_V4F32 : I<0, Pseudo, + (outs VR128:$dst), (ins VR128:$t, VR128:$f, i8imm:$cond), + "#CMOV_V4F32 PSEUDO!", + [(set VR128:$dst, + (v4f32 (X86cmov_new VR128:$t, VR128:$f, imm:$cond, + EFLAGS)))]>; + def NEW_CMOV_V2F64 : I<0, Pseudo, + (outs VR128:$dst), (ins VR128:$t, VR128:$f, i8imm:$cond), + "#CMOV_V2F64 PSEUDO!", + [(set VR128:$dst, + (v2f64 (X86cmov_new VR128:$t, VR128:$f, imm:$cond, + EFLAGS)))]>; + def NEW_CMOV_V2I64 : I<0, Pseudo, + (outs VR128:$dst), (ins VR128:$t, VR128:$f, i8imm:$cond), + "#CMOV_V2I64 PSEUDO!", + [(set VR128:$dst, + (v2i64 (X86cmov_new VR128:$t, VR128:$f, imm:$cond, + EFLAGS)))]>; } //===----------------------------------------------------------------------===// @@ -367,6 +400,14 @@ def UCOMISSrm: PSI<0x2E, MRMSrcMem, (outs), (ins FR32:$src1, f32mem:$src2), "ucomiss\t{$src2, $src1|$src1, $src2}", [(X86cmp FR32:$src1, (loadf32 addr:$src2))]>; + +def NEW_UCOMISSrr: PSI<0x2E, MRMSrcReg, (outs), (ins FR32:$src1, FR32:$src2), + "ucomiss\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new FR32:$src1, FR32:$src2), (implicit EFLAGS)]>; +def NEW_UCOMISSrm: PSI<0x2E, MRMSrcMem, (outs), (ins FR32:$src1, f32mem:$src2), + "ucomiss\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new FR32:$src1, (loadf32 addr:$src2)), + (implicit EFLAGS)]>; } // Defs = [EFLAGS] // Aliases to match intrinsics which expect XMM operand(s). @@ -397,6 +438,28 @@ def Int_COMISSrm: PSI<0x2F, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2), "comiss\t{$src2, $src1|$src1, $src2}", [(X86comi (v4f32 VR128:$src1), (load addr:$src2))]>; + +def NEW_Int_UCOMISSrr: PSI<0x2E, MRMSrcReg, (outs), + (ins VR128:$src1, VR128:$src2), + "ucomiss\t{$src2, $src1|$src1, $src2}", + [(X86ucomi_new (v4f32 VR128:$src1), VR128:$src2), + (implicit EFLAGS)]>; +def NEW_Int_UCOMISSrm: PSI<0x2E, MRMSrcMem, (outs), + (ins VR128:$src1, f128mem:$src2), + "ucomiss\t{$src2, $src1|$src1, $src2}", + [(X86ucomi_new (v4f32 VR128:$src1), (load addr:$src2)), + (implicit EFLAGS)]>; + +def NEW_Int_COMISSrr: PSI<0x2F, MRMSrcReg, (outs), + (ins VR128:$src1, VR128:$src2), + "comiss\t{$src2, $src1|$src1, $src2}", + [(X86comi_new (v4f32 VR128:$src1), VR128:$src2), + (implicit EFLAGS)]>; +def NEW_Int_COMISSrm: PSI<0x2F, MRMSrcMem, (outs), + (ins VR128:$src1, f128mem:$src2), + "comiss\t{$src2, $src1|$src1, $src2}", + [(X86comi_new (v4f32 VR128:$src1), (load addr:$src2)), + (implicit EFLAGS)]>; } // Defs = [EFLAGS] // Aliases of packed SSE1 instructions for scalar use. These all have names that @@ -1029,6 +1092,7 @@ "cmp${cc}sd\t{$src, $dst|$dst, $src}", []>; } +let Defs = [EFLAGS] in { def UCOMISDrr: PDI<0x2E, MRMSrcReg, (outs), (ins FR64:$src1, FR64:$src2), "ucomisd\t{$src2, $src1|$src1, $src2}", [(X86cmp FR64:$src1, FR64:$src2)]>; @@ -1036,6 +1100,15 @@ "ucomisd\t{$src2, $src1|$src1, $src2}", [(X86cmp FR64:$src1, (loadf64 addr:$src2))]>; +def NEW_UCOMISDrr: PDI<0x2E, MRMSrcReg, (outs), (ins FR64:$src1, FR64:$src2), + "ucomisd\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new FR64:$src1, FR64:$src2), (implicit EFLAGS)]>; +def NEW_UCOMISDrm: PDI<0x2E, MRMSrcMem, (outs), (ins FR64:$src1, f64mem:$src2), + "ucomisd\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new FR64:$src1, (loadf64 addr:$src2)), + (implicit EFLAGS)]>; +} + // Aliases to match intrinsics which expect XMM operand(s). let isTwoAddress = 1 in { def Int_CMPSDrr : SDI<0xC2, MRMSrcReg, @@ -1050,6 +1123,7 @@ (load addr:$src), imm:$cc))]>; } +let Defs = [EFLAGS] in { def Int_UCOMISDrr: PDI<0x2E, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2), "ucomisd\t{$src2, $src1|$src1, $src2}", [(X86ucomi (v2f64 VR128:$src1), (v2f64 VR128:$src2))]>; @@ -1064,6 +1138,29 @@ "comisd\t{$src2, $src1|$src1, $src2}", [(X86comi (v2f64 VR128:$src1), (load addr:$src2))]>; +def NEW_Int_UCOMISDrr: PDI<0x2E, MRMSrcReg, (outs), + (ins VR128:$src1, VR128:$src2), + "ucomisd\t{$src2, $src1|$src1, $src2}", + [(X86ucomi_new (v2f64 VR128:$src1), (v2f64 VR128:$src2)), + (implicit EFLAGS)]>; +def NEW_Int_UCOMISDrm: PDI<0x2E, MRMSrcMem, (outs), + (ins VR128:$src1, f128mem:$src2), + "ucomisd\t{$src2, $src1|$src1, $src2}", + [(X86ucomi_new (v2f64 VR128:$src1), (load addr:$src2)), + (implicit EFLAGS)]>; + +def NEW_Int_COMISDrr: PDI<0x2F, MRMSrcReg, (outs), + (ins VR128:$src1, VR128:$src2), + "comisd\t{$src2, $src1|$src1, $src2}", + [(X86comi_new (v2f64 VR128:$src1), (v2f64 VR128:$src2)), + (implicit EFLAGS)]>; +def NEW_Int_COMISDrm: PDI<0x2F, MRMSrcMem, (outs), + (ins VR128:$src1, f128mem:$src2), + "comisd\t{$src2, $src1|$src1, $src2}", + [(X86comi_new (v2f64 VR128:$src1), (load addr:$src2)), + (implicit EFLAGS)]>; +} // Defs = EFLAGS] + // Aliases of packed SSE2 instructions for scalar use. These all have names that // start with 'Fs'. 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=42285&r1=42284&r2=42285&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrX86-64.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrX86-64.td Mon Sep 24 20:57:46 2007 @@ -752,8 +752,60 @@ [(X86cmp GR64:$src1, i64immSExt8:$src2)]>; } // Defs = [EFLAGS] +let Defs = [EFLAGS] in { +let isCommutable = 1 in +def NEW_TEST64rr : RI<0x85, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), + "test{q}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and GR64:$src1, GR64:$src2), 0), + (implicit EFLAGS)]>; +def NEW_TEST64rm : RI<0x85, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2), + "test{q}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and GR64:$src1, (loadi64 addr:$src2)), 0), + (implicit EFLAGS)]>; +def NEW_TEST64ri32 : RIi32<0xF7, MRM0r, (outs), + (ins GR64:$src1, i64i32imm:$src2), + "test{q}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and GR64:$src1, i64immSExt32:$src2), 0), + (implicit EFLAGS)]>; +def NEW_TEST64mi32 : RIi32<0xF7, MRM0m, (outs), + (ins i64mem:$src1, i64i32imm:$src2), + "test{q}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (and (loadi64 addr:$src1), i64immSExt32:$src2), 0), + (implicit EFLAGS)]>; + +def NEW_CMP64rr : RI<0x39, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), + "cmp{q}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR64:$src1, GR64:$src2), + (implicit EFLAGS)]>; +def NEW_CMP64mr : RI<0x39, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), + "cmp{q}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (loadi64 addr:$src1), GR64:$src2), + (implicit EFLAGS)]>; +def NEW_CMP64rm : RI<0x3B, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2), + "cmp{q}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR64:$src1, (loadi64 addr:$src2)), + (implicit EFLAGS)]>; +def NEW_CMP64ri32 : RIi32<0x81, MRM7r, (outs), (ins GR64:$src1, i64i32imm:$src2), + "cmp{q}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR64:$src1, i64immSExt32:$src2), + (implicit EFLAGS)]>; +def NEW_CMP64mi32 : RIi32<0x81, MRM7m, (outs), + (ins i64mem:$src1, i64i32imm:$src2), + "cmp{q}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (loadi64 addr:$src1), i64immSExt32:$src2), + (implicit EFLAGS)]>; +def NEW_CMP64mi8 : RIi8<0x83, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2), + "cmp{q}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new (loadi64 addr:$src1), i64immSExt8:$src2), + (implicit EFLAGS)]>; +def NEW_CMP64ri8 : RIi8<0x83, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2), + "cmp{q}\t{$src2, $src1|$src1, $src2}", + [(X86cmp_new GR64:$src1, i64immSExt8:$src2), + (implicit EFLAGS)]>; +} // Defs = [EFLAGS] + // Conditional moves -let isTwoAddress = 1 in { +let Uses = [EFLAGS], isTwoAddress = 1 in { def CMOVB64rr : RI<0x42, MRMSrcReg, // if , TB; + X86_COND_NP))]>, TB; + +def NEW_CMOVB64rr : RI<0x42, MRMSrcReg, // if , TB; +def NEW_CMOVB64rm : RI<0x42, MRMSrcMem, // if , TB; +def NEW_CMOVAE64rr: RI<0x43, MRMSrcReg, // if >=u, GR64 = GR64 + (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), + "cmovae\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, GR64:$src2, + X86_COND_AE, EFLAGS))]>, TB; +def NEW_CMOVAE64rm: RI<0x43, MRMSrcMem, // if >=u, GR64 = [mem64] + (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), + "cmovae\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, (loadi64 addr:$src2), + X86_COND_AE, EFLAGS))]>, TB; +def NEW_CMOVE64rr : RI<0x44, MRMSrcReg, // if ==, GR64 = GR64 + (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), + "cmove\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, GR64:$src2, + X86_COND_E, EFLAGS))]>, TB; +def NEW_CMOVE64rm : RI<0x44, MRMSrcMem, // if ==, GR64 = [mem64] + (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), + "cmove\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, (loadi64 addr:$src2), + X86_COND_E, EFLAGS))]>, TB; +def NEW_CMOVNE64rr: RI<0x45, MRMSrcReg, // if !=, GR64 = GR64 + (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), + "cmovne\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, GR64:$src2, + X86_COND_NE, EFLAGS))]>, TB; +def NEW_CMOVNE64rm: RI<0x45, MRMSrcMem, // if !=, GR64 = [mem64] + (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), + "cmovne\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, (loadi64 addr:$src2), + X86_COND_NE, EFLAGS))]>, TB; +def NEW_CMOVBE64rr: RI<0x46, MRMSrcReg, // if <=u, GR64 = GR64 + (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), + "cmovbe\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, GR64:$src2, + X86_COND_BE, EFLAGS))]>, TB; +def NEW_CMOVBE64rm: RI<0x46, MRMSrcMem, // if <=u, GR64 = [mem64] + (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), + "cmovbe\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, (loadi64 addr:$src2), + X86_COND_BE, EFLAGS))]>, TB; +def NEW_CMOVA64rr : RI<0x47, MRMSrcReg, // if >u, GR64 = GR64 + (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), + "cmova\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, GR64:$src2, + X86_COND_A, EFLAGS))]>, TB; +def NEW_CMOVA64rm : RI<0x47, MRMSrcMem, // if >u, GR64 = [mem64] + (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), + "cmova\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, (loadi64 addr:$src2), + X86_COND_A, EFLAGS))]>, TB; +def NEW_CMOVL64rr : RI<0x4C, MRMSrcReg, // if , TB; +def NEW_CMOVL64rm : RI<0x4C, MRMSrcMem, // if , TB; +def NEW_CMOVGE64rr: RI<0x4D, MRMSrcReg, // if >=s, GR64 = GR64 + (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), + "cmovge\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, GR64:$src2, + X86_COND_GE, EFLAGS))]>, TB; +def NEW_CMOVGE64rm: RI<0x4D, MRMSrcMem, // if >=s, GR64 = [mem64] + (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), + "cmovge\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, (loadi64 addr:$src2), + X86_COND_GE, EFLAGS))]>, TB; +def NEW_CMOVLE64rr: RI<0x4E, MRMSrcReg, // if <=s, GR64 = GR64 + (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), + "cmovle\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, GR64:$src2, + X86_COND_LE, EFLAGS))]>, TB; +def NEW_CMOVLE64rm: RI<0x4E, MRMSrcMem, // if <=s, GR64 = [mem64] + (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), + "cmovle\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, (loadi64 addr:$src2), + X86_COND_LE, EFLAGS))]>, TB; +def NEW_CMOVG64rr : RI<0x4F, MRMSrcReg, // if >s, GR64 = GR64 + (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), + "cmovg\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, GR64:$src2, + X86_COND_G, EFLAGS))]>, TB; +def NEW_CMOVG64rm : RI<0x4F, MRMSrcMem, // if >s, GR64 = [mem64] + (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), + "cmovg\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, (loadi64 addr:$src2), + X86_COND_G, EFLAGS))]>, TB; +def NEW_CMOVS64rr : RI<0x48, MRMSrcReg, // if signed, GR64 = GR64 + (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), + "cmovs\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, GR64:$src2, + X86_COND_S, EFLAGS))]>, TB; +def NEW_CMOVS64rm : RI<0x48, MRMSrcMem, // if signed, GR64 = [mem64] + (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), + "cmovs\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, (loadi64 addr:$src2), + X86_COND_S, EFLAGS))]>, TB; +def NEW_CMOVNS64rr: RI<0x49, MRMSrcReg, // if !signed, GR64 = GR64 + (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), + "cmovns\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, GR64:$src2, + X86_COND_NS, EFLAGS))]>, TB; +def NEW_CMOVNS64rm: RI<0x49, MRMSrcMem, // if !signed, GR64 = [mem64] + (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), + "cmovns\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, (loadi64 addr:$src2), + X86_COND_NS, EFLAGS))]>, TB; +def NEW_CMOVP64rr : RI<0x4A, MRMSrcReg, // if parity, GR64 = GR64 + (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), + "cmovp\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, GR64:$src2, + X86_COND_P, EFLAGS))]>, TB; +def NEW_CMOVP64rm : RI<0x4A, MRMSrcMem, // if parity, GR64 = [mem64] + (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), + "cmovp\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, (loadi64 addr:$src2), + X86_COND_P, EFLAGS))]>, TB; +def NEW_CMOVNP64rr : RI<0x4B, MRMSrcReg, // if !parity, GR64 = GR64 + (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), + "cmovnp\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, GR64:$src2, + X86_COND_NP, EFLAGS))]>, TB; +def NEW_CMOVNP64rm : RI<0x4B, MRMSrcMem, // if !parity, GR64 = [mem64] + (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), + "cmovnp\t{$src2, $dst|$dst, $src2}", + [(set GR64:$dst, (X86cmov_new GR64:$src1, (loadi64 addr:$src2), + X86_COND_NP, EFLAGS))]>, TB; } // isTwoAddress //===----------------------------------------------------------------------===// @@ -1084,6 +1277,9 @@ def : Pat<(X86cmp GR64:$src1, 0), (TEST64rr GR64:$src1, GR64:$src1)>; +def : Pat<(parallel (X86cmp_new GR64:$src1, 0), (implicit EFLAGS)), + (NEW_TEST64rr GR64:$src1, GR64:$src1)>; + // {s|z}extload bool -> {s|z}extload byte def : Pat<(sextloadi64i1 addr:$src), (MOVSX64rm8 addr:$src)>; def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>; Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=42285&r1=42284&r2=42285&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Mon Sep 24 20:57:46 2007 @@ -677,6 +677,30 @@ { X86::MUL32r, X86::MUL32m }, { X86::MUL64r, X86::MUL64m }, { X86::MUL8r, X86::MUL8m }, + + // TEMPORARY + { X86::NEW_CMP16ri, X86::NEW_CMP16mi }, + { X86::NEW_CMP16ri8,X86::NEW_CMP16mi8 }, + { X86::NEW_CMP32ri, X86::NEW_CMP32mi }, + { X86::NEW_CMP32ri8,X86::NEW_CMP32mi8 }, + { X86::NEW_CMP64ri32,X86::NEW_CMP64mi32 }, + { X86::NEW_CMP64ri8,X86::NEW_CMP64mi8 }, + { X86::NEW_CMP8ri, X86::NEW_CMP8mi }, + { X86::NEW_SETAEr, X86::NEW_SETAEm }, + { X86::NEW_SETAr, X86::NEW_SETAm }, + { X86::NEW_SETBEr, X86::NEW_SETBEm }, + { X86::NEW_SETBr, X86::NEW_SETBm }, + { X86::NEW_SETEr, X86::NEW_SETEm }, + { X86::NEW_SETGEr, X86::NEW_SETGEm }, + { X86::NEW_SETGr, X86::NEW_SETGm }, + { X86::NEW_SETLEr, X86::NEW_SETLEm }, + { X86::NEW_SETLr, X86::NEW_SETLm }, + { X86::NEW_SETNEr, X86::NEW_SETNEm }, + { X86::NEW_SETNPr, X86::NEW_SETNPm }, + { X86::NEW_SETNSr, X86::NEW_SETNSm }, + { X86::NEW_SETPr, X86::NEW_SETPm }, + { X86::NEW_SETSr, X86::NEW_SETSm }, + { X86::SETAEr, X86::SETAEm }, { X86::SETAr, X86::SETAm }, { X86::SETBEr, X86::SETBEm }, @@ -787,6 +811,19 @@ { X86::MOVZX32rr8, X86::MOVZX32rm8 }, { X86::MOVZX64rr16, X86::MOVZX64rm16 }, { X86::MOVZX64rr8, X86::MOVZX64rm8 }, + + // TEMPORARY + { X86::NEW_Int_COMISDrr, X86::NEW_Int_COMISDrm }, + { X86::NEW_Int_COMISSrr, X86::NEW_Int_COMISSrm }, + { X86::NEW_Int_UCOMISDrr, X86::NEW_Int_UCOMISDrm }, + { X86::NEW_Int_UCOMISSrr, X86::NEW_Int_UCOMISSrm }, + { X86::NEW_TEST16rr, X86::NEW_TEST16rm }, + { X86::NEW_TEST32rr, X86::NEW_TEST32rm }, + { X86::NEW_TEST64rr, X86::NEW_TEST64rm }, + { X86::NEW_TEST8rr, X86::NEW_TEST8rm }, + { X86::NEW_UCOMISDrr, X86::NEW_UCOMISDrm }, + { X86::NEW_UCOMISSrr, X86::NEW_UCOMISSrm }, + { X86::PSHUFDri, X86::PSHUFDmi }, { X86::PSHUFHWri, X86::PSHUFHWmi }, { X86::PSHUFLWri, X86::PSHUFLWmi }, @@ -920,6 +957,51 @@ { X86::MULPSrr, X86::MULPSrm }, { X86::MULSDrr, X86::MULSDrm }, { X86::MULSSrr, X86::MULSSrm }, + + // TEMPORARY + { X86::NEW_CMOVA16rr, X86::NEW_CMOVA16rm }, + { X86::NEW_CMOVA32rr, X86::NEW_CMOVA32rm }, + { X86::NEW_CMOVA64rr, X86::NEW_CMOVA64rm }, + { X86::NEW_CMOVAE16rr, X86::NEW_CMOVAE16rm }, + { X86::NEW_CMOVAE32rr, X86::NEW_CMOVAE32rm }, + { X86::NEW_CMOVAE64rr, X86::NEW_CMOVAE64rm }, + { X86::NEW_CMOVB16rr, X86::NEW_CMOVB16rm }, + { X86::NEW_CMOVB32rr, X86::NEW_CMOVB32rm }, + { X86::NEW_CMOVB64rr, X86::NEW_CMOVB64rm }, + { X86::NEW_CMOVBE16rr, X86::NEW_CMOVBE16rm }, + { X86::NEW_CMOVBE32rr, X86::NEW_CMOVBE32rm }, + { X86::NEW_CMOVBE64rr, X86::NEW_CMOVBE64rm }, + { X86::NEW_CMOVE16rr, X86::NEW_CMOVE16rm }, + { X86::NEW_CMOVE32rr, X86::NEW_CMOVE32rm }, + { X86::NEW_CMOVE64rr, X86::NEW_CMOVE64rm }, + { X86::NEW_CMOVG16rr, X86::NEW_CMOVG16rm }, + { X86::NEW_CMOVG32rr, X86::NEW_CMOVG32rm }, + { X86::NEW_CMOVG64rr, X86::NEW_CMOVG64rm }, + { X86::NEW_CMOVGE16rr, X86::NEW_CMOVGE16rm }, + { X86::NEW_CMOVGE32rr, X86::NEW_CMOVGE32rm }, + { X86::NEW_CMOVGE64rr, X86::NEW_CMOVGE64rm }, + { X86::NEW_CMOVL16rr, X86::NEW_CMOVL16rm }, + { X86::NEW_CMOVL32rr, X86::NEW_CMOVL32rm }, + { X86::NEW_CMOVL64rr, X86::NEW_CMOVL64rm }, + { X86::NEW_CMOVLE16rr, X86::NEW_CMOVLE16rm }, + { X86::NEW_CMOVLE32rr, X86::NEW_CMOVLE32rm }, + { X86::NEW_CMOVLE64rr, X86::NEW_CMOVLE64rm }, + { X86::NEW_CMOVNE16rr, X86::NEW_CMOVNE16rm }, + { X86::NEW_CMOVNE32rr, X86::NEW_CMOVNE32rm }, + { X86::NEW_CMOVNE64rr, X86::NEW_CMOVNE64rm }, + { X86::NEW_CMOVNP16rr, X86::NEW_CMOVNP16rm }, + { X86::NEW_CMOVNP32rr, X86::NEW_CMOVNP32rm }, + { X86::NEW_CMOVNP64rr, X86::NEW_CMOVNP64rm }, + { X86::NEW_CMOVNS16rr, X86::NEW_CMOVNS16rm }, + { X86::NEW_CMOVNS32rr, X86::NEW_CMOVNS32rm }, + { X86::NEW_CMOVNS64rr, X86::NEW_CMOVNS64rm }, + { X86::NEW_CMOVP16rr, X86::NEW_CMOVP16rm }, + { X86::NEW_CMOVP32rr, X86::NEW_CMOVP32rm }, + { X86::NEW_CMOVP64rr, X86::NEW_CMOVP64rm }, + { X86::NEW_CMOVS16rr, X86::NEW_CMOVS16rm }, + { X86::NEW_CMOVS32rr, X86::NEW_CMOVS32rm }, + { X86::NEW_CMOVS64rr, X86::NEW_CMOVS64rm }, + { X86::OR16rr, X86::OR16rm }, { X86::OR32rr, X86::OR32rm }, { X86::OR64rr, X86::OR64rm }, From resistor at mac.com Mon Sep 24 19:10:58 2007 From: resistor at mac.com (Owen Anderson) Date: Tue, 25 Sep 2007 02:10:58 -0000 Subject: [llvm-commits] [llvm] r42286 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <200709250210.l8P2AwXN009437@zion.cs.uiuc.edu> Author: resistor Date: Mon Sep 24 21:10:58 2007 New Revision: 42286 URL: http://llvm.org/viewvc/llvm-project?rev=42286&view=rev Log: Fill in the sections about my contributions. Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=42286&r1=42285&r2=42286&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Mon Sep 24 21:10:58 2007 @@ -98,9 +98,17 @@
      -
    • Owen DSE and MemDep analysis
    • -
    • Owen GVN
    • -
    • Owen GVN-PRE, not in llvm-gcc
    • +
    • Owen Anderson wrote the new MemoryDependenceAnalysis pass, which provides + a lazy, caching layer on top of alias analysis. He then used it to rewrite + DeadStoreElimination which resulted in significantly better compile time in + common cases,
    • +
    • Owen implemented the new GVN pass, which is also based on + MemoryDependenceAnalysis. This pass replaces GCSE/LoadVN in the standard + set of passes, providing more aggressive optimization at a some-what + improved compile-time cost.
    • +
    • Owen implemented GVN-PRE, a partial redundancy elimination algorithm that + shares some details with the new GVN pass. It is still in need of compile + time tuning, and is not turned on by default.
    • Devang merged ETForest and DomTree into a single easier to use data structure.
    • Nick Lewycky improved loop trip count analysis to handle many more common From isanbard at gmail.com Mon Sep 24 19:51:18 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Sep 2007 02:51:18 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42287 - in /llvm-gcc-4.0/trunk/gcc: c-common.h llvm-backend.cpp objc/objc-act.c stub-objc.c Message-ID: <200709250251.l8P2pI2f010914@zion.cs.uiuc.edu> Author: void Date: Mon Sep 24 21:51:18 2007 New Revision: 42287 URL: http://llvm.org/viewvc/llvm-project?rev=42287&view=rev Log: During the processing of Objective-C "protocols", the objc frontend creates two decls for the protocol. One for the metadata and another for when it's referenced. However, protocols are "internal global", so when we do a lookup for the reference, it doesn't find the first decl because it's not "external". This will perform a second lookup for objective C protocols if we don't find it among the "external globals". Modified: llvm-gcc-4.0/trunk/gcc/c-common.h llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp llvm-gcc-4.0/trunk/gcc/objc/objc-act.c llvm-gcc-4.0/trunk/gcc/stub-objc.c Modified: llvm-gcc-4.0/trunk/gcc/c-common.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/c-common.h?rev=42287&r1=42286&r2=42287&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/c-common.h (original) +++ llvm-gcc-4.0/trunk/gcc/c-common.h Mon Sep 24 21:51:18 2007 @@ -1139,6 +1139,12 @@ extern void objc_remove_weak_read (tree*); /* APPLE LOCAL end radar 4426814 */ +/* APPLE LOCAL begin - LLVM radar 5476262 */ +#ifdef ENABLE_LLVM +extern bool objc_is_protocol_reference (const char *name); +#endif +/* APPLE LOCAL end - LLVM radar 5476262 */ + /* APPLE LOCAL begin C* language */ extern void objc_set_method_opt (int); void objc_finish_foreach_loop (location_t, tree, tree, tree, tree); Modified: llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp?rev=42287&r1=42286&r2=42287&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Mon Sep 24 21:51:18 2007 @@ -66,6 +66,7 @@ #include "function.h" #include "tree-inline.h" #include "langhooks.h" +#include "c-common.h" } // Non-zero if bytecode from PCH is successfully read. @@ -1060,6 +1061,14 @@ // If the global has a name, prevent multiple vars with the same name from // being created. GlobalVariable *GVE = TheModule->getGlobalVariable(Name); + + // And Objective-C "@protocol" will create a decl for the + // protocol metadata and then when the protocol is + // referenced. However, protocols have file-scope, so they + // aren't found in the GlobalVariable list unless we look at + // non-extern globals as well. + if (!GVE && c_dialect_objc() && objc_is_protocol_reference(Name)) + GVE = TheModule->getGlobalVariable(Name, true); if (GVE == 0) { GV = new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage,0, 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=42287&r1=42286&r2=42287&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Mon Sep 24 21:51:18 2007 @@ -11669,6 +11669,19 @@ } } +/* APPLE LOCAL begin - LLVM radar 5476262 */ +#ifdef ENABLE_LLVM +/* This routine returns true if the name is the same as a protocol + reference name. */ + +bool +objc_is_protocol_reference (const char *name) +{ + return flag_objc_abi == 2 && strstr (name, "_OBJC_PROTOCOL_$_") != 0; +} +#endif +/* APPLE LOCAL end - LLVM radar 5476262 */ + /* This routine builds the protocol_reference_chain for each protocol name used @protocol(MyProtocol) expression. IDENT is current protocol name. */ Modified: llvm-gcc-4.0/trunk/gcc/stub-objc.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/stub-objc.c?rev=42287&r1=42286&r2=42287&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/stub-objc.c (original) +++ llvm-gcc-4.0/trunk/gcc/stub-objc.c Mon Sep 24 21:51:18 2007 @@ -548,3 +548,13 @@ return false; } /* APPLE LOCAL end radar 4985544 */ + +/* APPLE LOCAL begin - LLVM radar 5476262 */ +#ifdef ENABLE_LLVM +bool +objc_is_protocol_reference (const char * ARG_UNUSED(name)) +{ + return false; +} +#endif +/* APPLE LOCAL end - LLVM radar 5476262 */ From isanbard at gmail.com Mon Sep 24 20:18:24 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Sep 2007 03:18:24 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42288 - /llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Message-ID: <200709250318.l8P3IOCu012055@zion.cs.uiuc.edu> Author: void Date: Mon Sep 24 22:18:23 2007 New Revision: 42288 URL: http://llvm.org/viewvc/llvm-project?rev=42288&view=rev Log: Tabs are the devil's work! Modified: llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp?rev=42288&r1=42287&r2=42288&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Mon Sep 24 22:18:23 2007 @@ -1060,7 +1060,7 @@ } else { // If the global has a name, prevent multiple vars with the same name from // being created. - GlobalVariable *GVE = TheModule->getGlobalVariable(Name); + GlobalVariable *GVE = TheModule->getGlobalVariable(Name, true); // And Objective-C "@protocol" will create a decl for the // protocol metadata and then when the protocol is @@ -1068,7 +1068,7 @@ // aren't found in the GlobalVariable list unless we look at // non-extern globals as well. if (!GVE && c_dialect_objc() && objc_is_protocol_reference(Name)) - GVE = TheModule->getGlobalVariable(Name, true); + GVE = TheModule->getGlobalVariable(Name, true); if (GVE == 0) { GV = new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage,0, From isanbard at gmail.com Mon Sep 24 20:21:18 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Sep 2007 03:21:18 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42289 - /llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Message-ID: <200709250321.l8P3LI1D012206@zion.cs.uiuc.edu> Author: void Date: Mon Sep 24 22:21:18 2007 New Revision: 42289 URL: http://llvm.org/viewvc/llvm-project?rev=42289&view=rev Log: Oops! Modified: llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp?rev=42289&r1=42288&r2=42289&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Mon Sep 24 22:21:18 2007 @@ -1060,7 +1060,7 @@ } else { // If the global has a name, prevent multiple vars with the same name from // being created. - GlobalVariable *GVE = TheModule->getGlobalVariable(Name, true); + GlobalVariable *GVE = TheModule->getGlobalVariable(Name); // And Objective-C "@protocol" will create a decl for the // protocol metadata and then when the protocol is From clattner at apple.com Mon Sep 24 22:32:37 2007 From: clattner at apple.com (Chris Lattner) Date: Mon, 24 Sep 2007 22:32:37 -0700 Subject: [llvm-commits] [llvm] r42278 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp In-Reply-To: <200709242154.l8OLsF56000956@zion.cs.uiuc.edu> References: <200709242154.l8OLsF56000956@zion.cs.uiuc.edu> Message-ID: <5F679400-DF52-4259-B01F-9448A3605697@apple.com> > URL: http://llvm.org/viewvc/llvm-project?rev=42278&view=rev > Log: > Add support on x86 for having Legalize lower ISD::LOCATION to > ISD::DEBUG_LOC > instead of ISD::LABEL with a manual .debug_line entry when the > assembler > supports .file and .loc directives. Nice! > > - // We don't have line number support yet. > + // Use the default ISD::LOCATION expansion, and tell Legalize it's > + // ok to use DEBUG_LOC if we have an assembler that supports it. > setOperationAction(ISD::LOCATION, MVT::Other, Expand); > - setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); > + if (TM.getTargetAsmInfo()->hasDotLocAndDotFile()) > + setOperationAction(ISD::DEBUG_LOC, MVT::Other, Legal); > + else > + setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); Would it make sense to move this to a superclass? It doesn't seem like any other definition would make sense. -chris From baldrick at free.fr Tue Sep 25 00:10:02 2007 From: baldrick at free.fr (Duncan Sands) Date: Tue, 25 Sep 2007 07:10:02 -0000 Subject: [llvm-commits] [llvm] r42294 - in /llvm/trunk/lib/VMCore: DominatorCalculation.h DominatorInternals.cpp Message-ID: <200709250710.l8P7A28b021647@zion.cs.uiuc.edu> Author: baldrick Date: Tue Sep 25 02:10:01 2007 New Revision: 42294 URL: http://llvm.org/viewvc/llvm-project?rev=42294&view=rev Log: Add missing end-of-file newlines. Modified: llvm/trunk/lib/VMCore/DominatorCalculation.h llvm/trunk/lib/VMCore/DominatorInternals.cpp Modified: llvm/trunk/lib/VMCore/DominatorCalculation.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/DominatorCalculation.h?rev=42294&r1=42293&r2=42294&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/DominatorCalculation.h (original) +++ llvm/trunk/lib/VMCore/DominatorCalculation.h Tue Sep 25 02:10:01 2007 @@ -104,4 +104,4 @@ } } -#endif \ No newline at end of file +#endif Modified: llvm/trunk/lib/VMCore/DominatorInternals.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/DominatorInternals.cpp?rev=42294&r1=42293&r2=42294&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/DominatorInternals.cpp (original) +++ llvm/trunk/lib/VMCore/DominatorInternals.cpp Tue Sep 25 02:10:01 2007 @@ -142,4 +142,4 @@ } -#endif \ No newline at end of file +#endif From baldrick at free.fr Tue Sep 25 06:53:22 2007 From: baldrick at free.fr (Duncan Sands) Date: Tue, 25 Sep 2007 13:53:22 -0000 Subject: [llvm-commits] [llvm] r42296 - /llvm/trunk/include/llvm/Type.h Message-ID: <200709251353.l8PDrMh3010932@zion.cs.uiuc.edu> Author: baldrick Date: Tue Sep 25 08:53:22 2007 New Revision: 42296 URL: http://llvm.org/viewvc/llvm-project?rev=42296&view=rev Log: Fix spelling. Modified: llvm/trunk/include/llvm/Type.h Modified: llvm/trunk/include/llvm/Type.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Type.h?rev=42296&r1=42295&r2=42296&view=diff ============================================================================== --- llvm/trunk/include/llvm/Type.h (original) +++ llvm/trunk/include/llvm/Type.h Tue Sep 25 08:53:22 2007 @@ -243,7 +243,7 @@ /// unsigned getPrimitiveSizeInBits() const; - /// getForwaredType - Return the type that this type has been resolved to if + /// getForwardedType - Return the type that this type has been resolved to if /// it has been resolved to anything. This is used to implement the /// union-find algorithm for type resolution, and shouldn't be used by general /// purpose clients. From djg at cray.com Tue Sep 25 08:10:50 2007 From: djg at cray.com (Dan Gohman) Date: Tue, 25 Sep 2007 15:10:50 -0000 Subject: [llvm-commits] [llvm] r42297 - in /llvm/trunk/lib: CodeGen/SelectionDAG/TargetLowering.cpp Target/X86/X86ISelLowering.cpp Message-ID: <200709251510.l8PFAohE013856@zion.cs.uiuc.edu> Author: djg Date: Tue Sep 25 10:10:49 2007 New Revision: 42297 URL: http://llvm.org/viewvc/llvm-project?rev=42297&view=rev Log: Move the setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand) and the check to see if the assembler supports .loc from X86TargetLowering into the superclass TargetLowering. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=42297&r1=42296&r2=42297&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Tue Sep 25 10:10:49 2007 @@ -20,6 +20,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Target/TargetAsmInfo.h" using namespace llvm; /// InitLibcallNames - Set default libcall names. @@ -169,6 +170,10 @@ InitLibcallNames(LibcallRoutineNames); InitCmpLibcallCCs(CmpLibcallCCs); + + // Tell Legalize whether the assembler supports DEBUG_LOC. + if (!TM.getTargetAsmInfo()->hasDotLocAndDotFile()) + setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); } TargetLowering::~TargetLowering() {} Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=42297&r1=42296&r2=42297&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Sep 25 10:10:49 2007 @@ -33,7 +33,6 @@ #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/MathExtras.h" -#include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetOptions.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ParameterAttributes.h" @@ -231,13 +230,8 @@ setOperationAction(ISD::MEMSET , MVT::Other, Custom); setOperationAction(ISD::MEMCPY , MVT::Other, Custom); - // Use the default ISD::LOCATION expansion, and tell Legalize it's - // ok to use DEBUG_LOC if we have an assembler that supports it. + // Use the default ISD::LOCATION expansion. setOperationAction(ISD::LOCATION, MVT::Other, Expand); - if (TM.getTargetAsmInfo()->hasDotLocAndDotFile()) - setOperationAction(ISD::DEBUG_LOC, MVT::Other, Legal); - else - setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); // FIXME - use subtarget debug flags if (!Subtarget->isTargetDarwin() && !Subtarget->isTargetELF() && From clattner at apple.com Tue Sep 25 09:35:36 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 25 Sep 2007 09:35:36 -0700 Subject: [llvm-commits] Duncan's VIEW_CONVERT_EXPR bug Message-ID: Duncan, please try this patch. If it helps your Ada issue, please apply it to 4.0 and 4.2. -Chris -------------- next part -------------- A non-text attachment was scrubbed... Name: vce.patch Type: application/octet-stream Size: 1294 bytes Desc: not available URL: -------------- next part -------------- From djg at cray.com Tue Sep 25 10:22:26 2007 From: djg at cray.com (Dan Gohman) Date: Tue, 25 Sep 2007 12:22:26 -0500 Subject: [llvm-commits] [llvm] r42285 - in /llvm/trunk/lib/Target/X86: X86FloatingPoint.cpp X86ISelLowering.cpp X86ISelLowering.h X86InstrFPStack.td X86InstrInfo.cpp X86InstrInfo.td X86InstrSSE.td X86InstrX86-64.td X86RegisterInfo.cpp Message-ID: <20070925172226.GB21991@village.us.cray.com> > +def X86cmp_new : SDNode<"X86ISD::CMP_NEW" , SDTX86CmpTest>; X86ISD::CMP_NEW SelectionDAG nodes return an i32 flags value, however the corresponding X86cmp_new pattern-matching nodes use SDTX86CmpTest, which has no result values. Is this intentional? If so, how is the discrepancy handled? > +def : Pat<(parallel (X86cmp_new GR8:$src1, 0), (implicit EFLAGS)), > + (NEW_TEST8rr GR8:$src1, GR8:$src1)>; In the SelectionDAG IR, an SDNode can return multiple results. However, in this GCC-RTL-like pattern langauge, where many things are supposed to directly correspond to SelectionDAG counterparts, nodes can return at most one result. They must be grouped together in a parallel to represent operations that have multiple results. It seems like this will result in more discrepancies. Am I misunderstanding something? Dan -- Dan Gohman, Cray Inc. From dalej at apple.com Tue Sep 25 10:25:01 2007 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 Sep 2007 17:25:01 -0000 Subject: [llvm-commits] [llvm] r42298 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200709251725.l8PHP7nS019168@zion.cs.uiuc.edu> Author: johannes Date: Tue Sep 25 12:25:00 2007 New Revision: 42298 URL: http://llvm.org/viewvc/llvm-project?rev=42298&view=rev Log: Fix long double<->shorter FP type conversions of zero, infinity, and NaNs. 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=42298&r1=42297&r2=42298&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Tue Sep 25 12:25:00 2007 @@ -1329,26 +1329,30 @@ /* Handle storage complications. If our new form is wider, re-allocate our bit pattern into wider storage. If it is narrower, we ignore the excess parts, but if narrowing to a - single part we need to free the old storage. */ + single part we need to free the old storage. + Be careful not to reference significandParts for zeroes + and infinities, since it aborts. */ if (newPartCount > oldPartCount) { integerPart *newParts; - newParts = new integerPart[newPartCount]; APInt::tcSet(newParts, 0, newPartCount); - APInt::tcAssign(newParts, significandParts(), oldPartCount); + if (category==fcNormal || category==fcNaN) + APInt::tcAssign(newParts, significandParts(), oldPartCount); freeSignificand(); significand.parts = newParts; } else if (newPartCount < oldPartCount) { /* Capture any lost fraction through truncation of parts so we get correct rounding whilst normalizing. */ - lostFraction = lostFractionThroughTruncation - (significandParts(), oldPartCount, toSemantics.precision); - if (newPartCount == 1) - { - integerPart newPart = significandParts()[0]; - freeSignificand(); - significand.part = newPart; - } + if (category==fcNormal) + lostFraction = lostFractionThroughTruncation + (significandParts(), oldPartCount, toSemantics.precision); + if (newPartCount == 1) { + integerPart newPart = 0; + if (category==fcNormal || category==fcNaN) + newPart = significandParts()[0]; + freeSignificand(); + significand.part = newPart; + } } if(category == fcNormal) { @@ -1356,6 +1360,19 @@ exponent += toSemantics.precision - semantics->precision; semantics = &toSemantics; fs = normalize(rounding_mode, lostFraction); + } else if (category == fcNaN) { + int shift = toSemantics.precision - semantics->precision; + // No normalization here, just truncate + if (shift>0) + APInt::tcShiftLeft(significandParts(), newPartCount, shift); + else if (shift < 0) + APInt::tcShiftRight(significandParts(), newPartCount, -shift); + // gcc forces the Quiet bit on, which means (float)(double)(float_sNan) + // does not give you back the same bits. This is dubious, and we + // don't currently do it. You're really supposed to get + // an invalid operation signal at runtime, but nobody does that. + semantics = &toSemantics; + fs = opOK; } else { semantics = &toSemantics; fs = opOK; @@ -1818,7 +1835,7 @@ } else if (myexponent==0xff && mysignificand==0) { // exponent, significand meaningless category = fcInfinity; - } else if (myexponent==0xff && (mysignificand & 0x400000)) { + } else if (myexponent==0xff && mysignificand!=0) { // sign, exponent, significand meaningless category = fcNaN; *significandParts() = mysignificand; From dpatel at apple.com Tue Sep 25 10:31:20 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 25 Sep 2007 17:31:20 -0000 Subject: [llvm-commits] [llvm] r42299 - in /llvm/trunk: lib/Transforms/Scalar/LoopIndexSplit.cpp test/Transforms/LoopIndexSplit/2007-09-24-UpdateIterationSpace.ll Message-ID: <200709251731.l8PHVMjT019539@zion.cs.uiuc.edu> Author: dpatel Date: Tue Sep 25 12:31:19 2007 New Revision: 42299 URL: http://llvm.org/viewvc/llvm-project?rev=42299&view=rev Log: Add transformation to update loop interation space. Now, for (i=A; i Y) do_something(); } is transformed into U=min(N,X); L=max(A,Y); for (i=L;igetPredicate() == ICmpInst::ICMP_SGT + || ExitCondition->getPredicate() == ICmpInst::ICMP_UGT + || ExitCondition->getPredicate() == ICmpInst::ICMP_SGE + || ExitCondition->getPredicate() == ICmpInst::ICMP_UGE) { + ExitCondition->swapOperands(); + if (ExitValueNum) + ExitValueNum = 0; + else + ExitValueNum = 1; + } + + Value *NUB = NULL; + Value *NLB = NULL; + Value *UB = ExitCondition->getOperand(ExitValueNum); + const Type *Ty = NV->getType(); + bool Sign = ExitCondition->isSignedPredicate(); + BasicBlock *Preheader = L->getLoopPreheader(); + Instruction *PHTerminator = Preheader->getTerminator(); + + assert (NV && "Unexpected value"); + switch (CI->getPredicate()) { case ICmpInst::ICMP_ULE: case ICmpInst::ICMP_SLE: @@ -740,9 +761,15 @@ // for (i = LB; i < NUB ; ++i) // LOOP_BODY // - - - + if (ExitCondition->getPredicate() == ICmpInst::ICMP_SLT + || ExitCondition->getPredicate() == ICmpInst::ICMP_ULT) { + Value *A = BinaryOperator::createAdd(NV, ConstantInt::get(Ty, 1, Sign), + "lsplit.add", PHTerminator); + Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, + A, UB,"lsplit,c", PHTerminator); + NUB = new SelectInst (C, A, UB, "lsplit.nub", PHTerminator); + } + // for (i = LB; i <= UB; ++i) // if (i <= NV && ...) // LOOP_BODY @@ -752,6 +779,12 @@ // for (i = LB; i <= NUB ; ++i) // LOOP_BODY // + else if (ExitCondition->getPredicate() == ICmpInst::ICMP_SLE + || ExitCondition->getPredicate() == ICmpInst::ICMP_ULE) { + Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, + NV, UB, "lsplit.c", PHTerminator); + NUB = new SelectInst (C, NV, UB, "lsplit.nub", PHTerminator); + } break; case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_SLT: @@ -764,8 +797,12 @@ // for (i = LB; i < NUB ; ++i) // LOOP_BODY // - - + if (ExitCondition->getPredicate() == ICmpInst::ICMP_SLT + || ExitCondition->getPredicate() == ICmpInst::ICMP_ULT) { + Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, + NV, UB, "lsplit.c", PHTerminator); + NUB = new SelectInst (C, NV, UB, "lsplit.nub", PHTerminator); + } // for (i = LB; i <= UB; ++i) // if (i < NV && ...) @@ -776,6 +813,14 @@ // for (i = LB; i <= NUB ; ++i) // LOOP_BODY // + else if (ExitCondition->getPredicate() == ICmpInst::ICMP_SLE + || ExitCondition->getPredicate() == ICmpInst::ICMP_ULE) { + Value *S = BinaryOperator::createSub(NV, ConstantInt::get(Ty, 1, Sign), + "lsplit.add", PHTerminator); + Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, + S, UB, "lsplit.c", PHTerminator); + NUB = new SelectInst (C, S, UB, "lsplit.nub", PHTerminator); + } break; case ICmpInst::ICMP_UGE: case ICmpInst::ICMP_SGE: @@ -788,6 +833,11 @@ // for (i = NLB; i (< or <=) UB ; ++i) // LOOP_BODY // + { + Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, + NV, StartValue, "lsplit.c", PHTerminator); + NLB = new SelectInst (C, StartValue, NV, "lsplit.nlb", PHTerminator); + } break; case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_SGT: @@ -800,10 +850,26 @@ // for (i = NLB; i (< or <=) UB ; ++i) // LOOP_BODY // + { + Value *A = BinaryOperator::createAdd(NV, ConstantInt::get(Ty, 1, Sign), + "lsplit.add", PHTerminator); + Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, + A, StartValue, "lsplit.c", PHTerminator); + NLB = new SelectInst (C, StartValue, A, "lsplit.nlb", PHTerminator); + } break; default: assert ( 0 && "Unexpected split condition predicate"); } + + if (NLB) { + unsigned i = IndVar->getBasicBlockIndex(Preheader); + IndVar->setIncomingValue(i, NLB); + } + + if (NUB) { + ExitCondition->setOperand(ExitValueNum, NUB); + } } /// updateLoopIterationSpace - Current loop body is covered by an AND /// instruction whose operands compares induction variables with loop @@ -811,6 +877,9 @@ /// updating appropriate start and end values for induction variable. bool LoopIndexSplit::updateLoopIterationSpace(SplitInfo &SD) { BasicBlock *Header = L->getHeader(); + BasicBlock *ExitingBlock = ExitCondition->getParent(); + BasicBlock *SplitCondBlock = SD.SplitCondition->getParent(); + ICmpInst *Op0 = cast(SD.SplitCondition->getOperand(0)); ICmpInst *Op1 = cast(SD.SplitCondition->getOperand(1)); @@ -865,11 +934,83 @@ // loop may not be eliminated. if (!safeExitingBlock(SD, ExitCondition->getParent())) return false; - + + // Verify that loop exiting block has only two predecessor, where one predecessor + // is split condition block. The other predecessor will become exiting block's + // dominator after CFG is updated. TODO : Handle CFG's where exiting block has + // more then two predecessors. This requires extra work in updating dominator + // information. + BasicBlock *ExitingBBPred = NULL; + for (pred_iterator PI = pred_begin(ExitingBlock), PE = pred_end(ExitingBlock); + PI != PE; ++PI) { + BasicBlock *BB = *PI; + if (SplitCondBlock == BB) + continue; + if (ExitingBBPred) + return false; + else + ExitingBBPred = BB; + } + + // Update loop bounds to absorb Op0 check. updateLoopBounds(Op0); + // Update loop bounds to absorb Op1 check. updateLoopBounds(Op1); + // Update CFG - return false; + + // Unconditionally connect split block to its remaining successor. + BranchInst *SplitTerminator = + cast(SplitCondBlock->getTerminator()); + BasicBlock *Succ0 = SplitTerminator->getSuccessor(0); + BasicBlock *Succ1 = SplitTerminator->getSuccessor(1); + if (Succ0 == ExitCondition->getParent()) + SplitTerminator->setUnconditionalDest(Succ1); + else + SplitTerminator->setUnconditionalDest(Succ0); + + // Remove split condition. + SD.SplitCondition->eraseFromParent(); + if (Op0->use_begin() == Op0->use_end()) + Op0->eraseFromParent(); + if (Op1->use_begin() == Op1->use_end()) + Op1->eraseFromParent(); + + BranchInst *ExitInsn = + dyn_cast(ExitingBlock->getTerminator()); + assert (ExitInsn && "Unable to find suitable loop exit branch"); + BasicBlock *ExitBlock = ExitInsn->getSuccessor(1); + if (L->contains(ExitBlock)) + ExitBlock = ExitInsn->getSuccessor(0); + + // Update domiantor info. Now, ExitingBlock has only one predecessor, + // ExitingBBPred, and it is ExitingBlock's immediate domiantor. + DT->changeImmediateDominator(ExitingBlock, ExitingBBPred); + + // If ExitingBlock is a member of loop BB's DF list then replace it with + // loop header and exit block. + for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); + I != E; ++I) { + BasicBlock *BB = *I; + if (BB == Header || BB == ExitingBlock) + continue; + DominanceFrontier::iterator BBDF = DF->find(BB); + DominanceFrontier::DomSetType::iterator DomSetI = BBDF->second.begin(); + DominanceFrontier::DomSetType::iterator DomSetE = BBDF->second.end(); + while (DomSetI != DomSetE) { + DominanceFrontier::DomSetType::iterator CurrentItr = DomSetI; + ++DomSetI; + BasicBlock *DFBB = *CurrentItr; + if (DFBB == ExitingBlock) { + BBDF->second.erase(DFBB); + BBDF->second.insert(Header); + if (Header != ExitingBlock) + BBDF->second.insert(ExitBlock); + } + } + } + + return return; } Added: llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-24-UpdateIterationSpace.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-24-UpdateIterationSpace.ll?rev=42299&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-24-UpdateIterationSpace.ll (added) +++ llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-24-UpdateIterationSpace.ll Tue Sep 25 12:31:19 2007 @@ -0,0 +1,57 @@ + +; Update loop iteraton space to eliminate condition inside loop. +; RUN: llvm-as < %s | opt -loop-index-split | llvm-dis | not grep bothcond +define void @test(float* %x, i32 %ndat, float** %y, float %xcen, i32 %xmin, i32 %xmax, float %sigmal, float %contribution) { +entry: + %tmp519 = icmp sgt i32 %xmin, %xmax ; [#uses=1] + br i1 %tmp519, label %return, label %bb.preheader + +bb.preheader: ; preds = %entry + %tmp3031 = fpext float %contribution to double ; [#uses=1] + %tmp32 = mul double %tmp3031, 5.000000e-01 ; [#uses=1] + %tmp3839 = fpext float %sigmal to double ; [#uses=1] + br label %bb + +bb: ; preds = %bb.preheader, %cond_next45 + %i.01.0 = phi i32 [ %tmp47, %cond_next45 ], [ %xmin, %bb.preheader ] ; [#uses=6] + %tmp2 = icmp sgt i32 %i.01.0, -1 ; [#uses=1] + %tmp6 = icmp slt i32 %i.01.0, %ndat ; [#uses=1] + %bothcond = and i1 %tmp2, %tmp6 ; [#uses=1] + br i1 %bothcond, label %cond_true9, label %cond_next45 + +cond_true9: ; preds = %bb + %tmp12 = getelementptr float* %x, i32 %i.01.0 ; [#uses=1] + %tmp13 = load float* %tmp12, align 4 ; [#uses=1] + %tmp15 = sub float %xcen, %tmp13 ; [#uses=1] + %tmp16 = tail call float @fabsf( float %tmp15 ) ; [#uses=1] + %tmp18 = fdiv float %tmp16, %sigmal ; [#uses=1] + %tmp21 = load float** %y, align 4 ; [#uses=2] + %tmp27 = getelementptr float* %tmp21, i32 %i.01.0 ; [#uses=1] + %tmp28 = load float* %tmp27, align 4 ; [#uses=1] + %tmp2829 = fpext float %tmp28 to double ; [#uses=1] + %tmp34 = sub float -0.000000e+00, %tmp18 ; [#uses=1] + %tmp3435 = fpext float %tmp34 to double ; [#uses=1] + %tmp36 = tail call double @exp( double %tmp3435 ) ; [#uses=1] + %tmp37 = mul double %tmp32, %tmp36 ; [#uses=1] + %tmp40 = fdiv double %tmp37, %tmp3839 ; [#uses=1] + %tmp41 = add double %tmp2829, %tmp40 ; [#uses=1] + %tmp4142 = fptrunc double %tmp41 to float ; [#uses=1] + %tmp44 = getelementptr float* %tmp21, i32 %i.01.0 ; [#uses=1] + store float %tmp4142, float* %tmp44, align 4 + br label %cond_next45 + +cond_next45: ; preds = %bb, %cond_true9 + %tmp47 = add i32 %i.01.0, 1 ; [#uses=2] + %tmp51 = icmp sgt i32 %tmp47, %xmax ; [#uses=1] + br i1 %tmp51, label %return.loopexit, label %bb + +return.loopexit: ; preds = %cond_next45 + br label %return + +return: ; preds = %return.loopexit, %entry + ret void +} + +declare float @fabsf(float) + +declare double @exp(double) From dpatel at apple.com Tue Sep 25 10:43:08 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 25 Sep 2007 17:43:08 -0000 Subject: [llvm-commits] [llvm] r42300 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200709251743.l8PHh8FV020177@zion.cs.uiuc.edu> Author: dpatel Date: Tue Sep 25 12:43:08 2007 New Revision: 42300 URL: http://llvm.org/viewvc/llvm-project?rev=42300&view=rev Log: doh.. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=42300&r1=42299&r2=42300&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Tue Sep 25 12:43:08 2007 @@ -1010,7 +1010,7 @@ } } - return return; + return true; } From evan.cheng at apple.com Tue Sep 25 10:47:38 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 Sep 2007 17:47:38 -0000 Subject: [llvm-commits] [llvm] r42302 - /llvm/trunk/test/CodeGen/X86/2006-11-17-IllegalMove.ll Message-ID: <200709251747.l8PHlcYM020411@zion.cs.uiuc.edu> Author: evancheng Date: Tue Sep 25 12:47:38 2007 New Revision: 42302 URL: http://llvm.org/viewvc/llvm-project?rev=42302&view=rev Log: Forgot to check in the changes. Fix test case so it doesn't break with any scheduling changes. Modified: llvm/trunk/test/CodeGen/X86/2006-11-17-IllegalMove.ll Modified: llvm/trunk/test/CodeGen/X86/2006-11-17-IllegalMove.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2006-11-17-IllegalMove.ll?rev=42302&r1=42301&r2=42302&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2006-11-17-IllegalMove.ll (original) +++ llvm/trunk/test/CodeGen/X86/2006-11-17-IllegalMove.ll Tue Sep 25 12:47:38 2007 @@ -1,7 +1,7 @@ ; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86-64 | \ -; RUN: not grep {movb %sil, %ah} +; RUN: grep movb | count 2 ; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86-64 | \ -; RUN: grep {movzbw %al, %ax} +; RUN: grep movzbw void %handle_vector_size_attribute() { entry: From dalej at apple.com Tue Sep 25 10:50:55 2007 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 Sep 2007 17:50:55 -0000 Subject: [llvm-commits] [llvm] r42303 - in /llvm/trunk/test/CodeGen/X86: ldzero.ll nancvt.ll Message-ID: <200709251750.l8PHotYr020560@zion.cs.uiuc.edu> Author: johannes Date: Tue Sep 25 12:50:55 2007 New Revision: 42303 URL: http://llvm.org/viewvc/llvm-project?rev=42303&view=rev Log: Some tests for APFloat conversions. Added: llvm/trunk/test/CodeGen/X86/ldzero.ll llvm/trunk/test/CodeGen/X86/nancvt.ll Added: llvm/trunk/test/CodeGen/X86/ldzero.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/ldzero.ll?rev=42303&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/ldzero.ll (added) +++ llvm/trunk/test/CodeGen/X86/ldzero.ll Tue Sep 25 12:50:55 2007 @@ -0,0 +1,43 @@ +; RUN: llvm-as < %s | llc +; verify PR 1700 is still fixed +; ModuleID = 'hh.c' +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" + +define x86_fp80 @x() { +entry: + %retval = alloca x86_fp80, align 16 ; [#uses=2] + %tmp = alloca x86_fp80, align 16 ; [#uses=2] + %d = alloca double, align 8 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store double 0.000000e+00, double* %d, align 8 + %tmp1 = load double* %d, align 8 ; [#uses=1] + %tmp12 = fpext double %tmp1 to x86_fp80 ; [#uses=1] + store x86_fp80 %tmp12, x86_fp80* %tmp, align 16 + %tmp3 = load x86_fp80* %tmp, align 16 ; [#uses=1] + store x86_fp80 %tmp3, x86_fp80* %retval, align 16 + br label %return + +return: ; preds = %entry + %retval4 = load x86_fp80* %retval ; [#uses=1] + ret x86_fp80 %retval4 +} + +define double @y() { +entry: + %retval = alloca double, align 8 ; [#uses=2] + %tmp = alloca double, align 8 ; [#uses=2] + %ld = alloca x86_fp80, align 16 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store x86_fp80 0xK00000000000000000000, x86_fp80* %ld, align 16 + %tmp1 = load x86_fp80* %ld, align 16 ; [#uses=1] + %tmp12 = fptrunc x86_fp80 %tmp1 to double ; [#uses=1] + store double %tmp12, double* %tmp, align 8 + %tmp3 = load double* %tmp, align 8 ; [#uses=1] + store double %tmp3, double* %retval, align 8 + br label %return + +return: ; preds = %entry + %retval4 = load double* %retval ; [#uses=1] + ret double %retval4 +} Added: llvm/trunk/test/CodeGen/X86/nancvt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/nancvt.ll?rev=42303&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/nancvt.ll (added) +++ llvm/trunk/test/CodeGen/X86/nancvt.ll Tue Sep 25 12:50:55 2007 @@ -0,0 +1,180 @@ +; RUN: llvm-as < %s | opt -std-compile-opts | llc | grep 2147027116 | count 3 +; RUN: llvm-as < %s | opt -std-compile-opts | llc | grep 2147228864 | count 3 +; RUN: llvm-as < %s | opt -std-compile-opts | llc | grep 2146502828 | count 3 +; RUN: llvm-as < %s | opt -std-compile-opts | llc | grep 2143034560 | count 3 +; Compile time conversions of NaNs. +; ModuleID = 'nan2.c' +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..0anon = type { float } + %struct..1anon = type { double } + at fnan = constant [3 x i32] [ i32 2143831397, i32 2143831396, i32 2143831398 ] ; <[3 x i32]*> [#uses=1] + at dnan = constant [3 x i64] [ i64 9223235251041752696, i64 9223235251041752697, i64 9223235250773317239 ], align 8 ; <[3 x i64]*> [#uses=1] + at fsnan = constant [3 x i32] [ i32 2139637093, i32 2139637092, i32 2139637094 ] ; <[3 x i32]*> [#uses=1] + at dsnan = constant [3 x i64] [ i64 9220983451228067448, i64 9220983451228067449, i64 9220983450959631991 ], align 8 ; <[3 x i64]*> [#uses=1] + at .str = internal constant [10 x i8] c"%08x%08x\0A\00" ; <[10 x i8]*> [#uses=2] + at .str1 = internal constant [6 x i8] c"%08x\0A\00" ; <[6 x i8]*> [#uses=2] + +define i32 @main() { +entry: + %retval = alloca i32, align 4 ; [#uses=1] + %i = alloca i32, align 4 ; [#uses=20] + %uf = alloca %struct..0anon, align 4 ; <%struct..0anon*> [#uses=8] + %ud = alloca %struct..1anon, align 8 ; <%struct..1anon*> [#uses=10] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i32 0, i32* %i, align 4 + br label %bb23 + +bb: ; preds = %bb23 + %tmp = load i32* %i, align 4 ; [#uses=1] + %tmp1 = getelementptr [3 x i32]* @fnan, i32 0, i32 %tmp ; [#uses=1] + %tmp2 = load i32* %tmp1, align 4 ; [#uses=1] + %tmp3 = getelementptr %struct..0anon* %uf, i32 0, i32 0 ; [#uses=1] + %tmp34 = bitcast float* %tmp3 to i32* ; [#uses=1] + store i32 %tmp2, i32* %tmp34, align 4 + %tmp5 = getelementptr %struct..0anon* %uf, i32 0, i32 0 ; [#uses=1] + %tmp6 = load float* %tmp5, align 4 ; [#uses=1] + %tmp67 = fpext float %tmp6 to double ; [#uses=1] + %tmp8 = getelementptr %struct..1anon* %ud, i32 0, i32 0 ; [#uses=1] + store double %tmp67, double* %tmp8, align 8 + %tmp9 = getelementptr %struct..1anon* %ud, i32 0, i32 0 ; [#uses=1] + %tmp910 = bitcast double* %tmp9 to i64* ; [#uses=1] + %tmp11 = load i64* %tmp910, align 8 ; [#uses=1] + %tmp1112 = trunc i64 %tmp11 to i32 ; [#uses=1] + %tmp13 = and i32 %tmp1112, -1 ; [#uses=1] + %tmp14 = getelementptr %struct..1anon* %ud, i32 0, i32 0 ; [#uses=1] + %tmp1415 = bitcast double* %tmp14 to i64* ; [#uses=1] + %tmp16 = load i64* %tmp1415, align 8 ; [#uses=1] + %.cast = zext i32 32 to i64 ; [#uses=1] + %tmp17 = ashr i64 %tmp16, %.cast ; [#uses=1] + %tmp1718 = trunc i64 %tmp17 to i32 ; [#uses=1] + %tmp19 = getelementptr [10 x i8]* @.str, i32 0, i32 0 ; [#uses=1] + %tmp20 = call i32 (i8*, ...)* @printf( i8* %tmp19, i32 %tmp1718, i32 %tmp13 ) ; [#uses=0] + %tmp21 = load i32* %i, align 4 ; [#uses=1] + %tmp22 = add i32 %tmp21, 1 ; [#uses=1] + store i32 %tmp22, i32* %i, align 4 + br label %bb23 + +bb23: ; preds = %bb, %entry + %tmp24 = load i32* %i, align 4 ; [#uses=1] + %tmp25 = icmp sle i32 %tmp24, 2 ; [#uses=1] + %tmp2526 = zext i1 %tmp25 to i8 ; [#uses=1] + %toBool = icmp ne i8 %tmp2526, 0 ; [#uses=1] + br i1 %toBool, label %bb, label %bb27 + +bb27: ; preds = %bb23 + store i32 0, i32* %i, align 4 + br label %bb46 + +bb28: ; preds = %bb46 + %tmp29 = load i32* %i, align 4 ; [#uses=1] + %tmp30 = getelementptr [3 x i64]* @dnan, i32 0, i32 %tmp29 ; [#uses=1] + %tmp31 = load i64* %tmp30, align 8 ; [#uses=1] + %tmp32 = getelementptr %struct..1anon* %ud, i32 0, i32 0 ; [#uses=1] + %tmp3233 = bitcast double* %tmp32 to i64* ; [#uses=1] + store i64 %tmp31, i64* %tmp3233, align 8 + %tmp35 = getelementptr %struct..1anon* %ud, i32 0, i32 0 ; [#uses=1] + %tmp36 = load double* %tmp35, align 8 ; [#uses=1] + %tmp3637 = fptrunc double %tmp36 to float ; [#uses=1] + %tmp38 = getelementptr %struct..0anon* %uf, i32 0, i32 0 ; [#uses=1] + store float %tmp3637, float* %tmp38, align 4 + %tmp39 = getelementptr %struct..0anon* %uf, i32 0, i32 0 ; [#uses=1] + %tmp3940 = bitcast float* %tmp39 to i32* ; [#uses=1] + %tmp41 = load i32* %tmp3940, align 4 ; [#uses=1] + %tmp42 = getelementptr [6 x i8]* @.str1, i32 0, i32 0 ; [#uses=1] + %tmp43 = call i32 (i8*, ...)* @printf( i8* %tmp42, i32 %tmp41 ) ; [#uses=0] + %tmp44 = load i32* %i, align 4 ; [#uses=1] + %tmp45 = add i32 %tmp44, 1 ; [#uses=1] + store i32 %tmp45, i32* %i, align 4 + br label %bb46 + +bb46: ; preds = %bb28, %bb27 + %tmp47 = load i32* %i, align 4 ; [#uses=1] + %tmp48 = icmp sle i32 %tmp47, 2 ; [#uses=1] + %tmp4849 = zext i1 %tmp48 to i8 ; [#uses=1] + %toBool50 = icmp ne i8 %tmp4849, 0 ; [#uses=1] + br i1 %toBool50, label %bb28, label %bb51 + +bb51: ; preds = %bb46 + store i32 0, i32* %i, align 4 + br label %bb78 + +bb52: ; preds = %bb78 + %tmp53 = load i32* %i, align 4 ; [#uses=1] + %tmp54 = getelementptr [3 x i32]* @fsnan, i32 0, i32 %tmp53 ; [#uses=1] + %tmp55 = load i32* %tmp54, align 4 ; [#uses=1] + %tmp56 = getelementptr %struct..0anon* %uf, i32 0, i32 0 ; [#uses=1] + %tmp5657 = bitcast float* %tmp56 to i32* ; [#uses=1] + store i32 %tmp55, i32* %tmp5657, align 4 + %tmp58 = getelementptr %struct..0anon* %uf, i32 0, i32 0 ; [#uses=1] + %tmp59 = load float* %tmp58, align 4 ; [#uses=1] + %tmp5960 = fpext float %tmp59 to double ; [#uses=1] + %tmp61 = getelementptr %struct..1anon* %ud, i32 0, i32 0 ; [#uses=1] + store double %tmp5960, double* %tmp61, align 8 + %tmp62 = getelementptr %struct..1anon* %ud, i32 0, i32 0 ; [#uses=1] + %tmp6263 = bitcast double* %tmp62 to i64* ; [#uses=1] + %tmp64 = load i64* %tmp6263, align 8 ; [#uses=1] + %tmp6465 = trunc i64 %tmp64 to i32 ; [#uses=1] + %tmp66 = and i32 %tmp6465, -1 ; [#uses=1] + %tmp68 = getelementptr %struct..1anon* %ud, i32 0, i32 0 ; [#uses=1] + %tmp6869 = bitcast double* %tmp68 to i64* ; [#uses=1] + %tmp70 = load i64* %tmp6869, align 8 ; [#uses=1] + %.cast71 = zext i32 32 to i64 ; [#uses=1] + %tmp72 = ashr i64 %tmp70, %.cast71 ; [#uses=1] + %tmp7273 = trunc i64 %tmp72 to i32 ; [#uses=1] + %tmp74 = getelementptr [10 x i8]* @.str, i32 0, i32 0 ; [#uses=1] + %tmp75 = call i32 (i8*, ...)* @printf( i8* %tmp74, i32 %tmp7273, i32 %tmp66 ) ; [#uses=0] + %tmp76 = load i32* %i, align 4 ; [#uses=1] + %tmp77 = add i32 %tmp76, 1 ; [#uses=1] + store i32 %tmp77, i32* %i, align 4 + br label %bb78 + +bb78: ; preds = %bb52, %bb51 + %tmp79 = load i32* %i, align 4 ; [#uses=1] + %tmp80 = icmp sle i32 %tmp79, 2 ; [#uses=1] + %tmp8081 = zext i1 %tmp80 to i8 ; [#uses=1] + %toBool82 = icmp ne i8 %tmp8081, 0 ; [#uses=1] + br i1 %toBool82, label %bb52, label %bb83 + +bb83: ; preds = %bb78 + store i32 0, i32* %i, align 4 + br label %bb101 + +bb84: ; preds = %bb101 + %tmp85 = load i32* %i, align 4 ; [#uses=1] + %tmp86 = getelementptr [3 x i64]* @dsnan, i32 0, i32 %tmp85 ; [#uses=1] + %tmp87 = load i64* %tmp86, align 8 ; [#uses=1] + %tmp88 = getelementptr %struct..1anon* %ud, i32 0, i32 0 ; [#uses=1] + %tmp8889 = bitcast double* %tmp88 to i64* ; [#uses=1] + store i64 %tmp87, i64* %tmp8889, align 8 + %tmp90 = getelementptr %struct..1anon* %ud, i32 0, i32 0 ; [#uses=1] + %tmp91 = load double* %tmp90, align 8 ; [#uses=1] + %tmp9192 = fptrunc double %tmp91 to float ; [#uses=1] + %tmp93 = getelementptr %struct..0anon* %uf, i32 0, i32 0 ; [#uses=1] + store float %tmp9192, float* %tmp93, align 4 + %tmp94 = getelementptr %struct..0anon* %uf, i32 0, i32 0 ; [#uses=1] + %tmp9495 = bitcast float* %tmp94 to i32* ; [#uses=1] + %tmp96 = load i32* %tmp9495, align 4 ; [#uses=1] + %tmp97 = getelementptr [6 x i8]* @.str1, i32 0, i32 0 ; [#uses=1] + %tmp98 = call i32 (i8*, ...)* @printf( i8* %tmp97, i32 %tmp96 ) ; [#uses=0] + %tmp99 = load i32* %i, align 4 ; [#uses=1] + %tmp100 = add i32 %tmp99, 1 ; [#uses=1] + store i32 %tmp100, i32* %i, align 4 + br label %bb101 + +bb101: ; preds = %bb84, %bb83 + %tmp102 = load i32* %i, align 4 ; [#uses=1] + %tmp103 = icmp sle i32 %tmp102, 2 ; [#uses=1] + %tmp103104 = zext i1 %tmp103 to i8 ; [#uses=1] + %toBool105 = icmp ne i8 %tmp103104, 0 ; [#uses=1] + br i1 %toBool105, label %bb84, label %bb106 + +bb106: ; preds = %bb101 + br label %return + +return: ; preds = %bb106 + %retval107 = load i32* %retval ; [#uses=1] + ret i32 %retval107 +} + +declare i32 @printf(i8*, ...) From dpatel at apple.com Tue Sep 25 10:55:50 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 25 Sep 2007 17:55:50 -0000 Subject: [llvm-commits] [llvm] r42306 - /llvm/trunk/lib/Transforms/Scalar/LICM.cpp Message-ID: <200709251755.l8PHtpip020833@zion.cs.uiuc.edu> Author: dpatel Date: Tue Sep 25 12:55:50 2007 New Revision: 42306 URL: http://llvm.org/viewvc/llvm-project?rev=42306&view=rev Log: Do not reserve DOM check for GetElementPtrInst. Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=42306&r1=42305&r2=42306&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Tue Sep 25 12:55:50 2007 @@ -811,30 +811,31 @@ // condition which may not yet folded. if (isa(GEP->getOperand(0))) PointerOk = false; + } - // If GEP is use is not dominating loop exit then promoting - // GEP may expose unsafe load and store instructions unconditinally. - if (PointerOk) - for(Value::use_iterator UI = V->use_begin(), UE = V->use_end(); - UI != UE && PointerOk; ++UI) { - Instruction *Use = dyn_cast(*UI); - if (!Use) - continue; - for (SmallVector::iterator - ExitI = LoopExits.begin(), ExitE = LoopExits.end(); - ExitI != ExitE; ++ExitI) { - Instruction *Ex = *ExitI; - if (!DT->dominates(Use, Ex)){ - PointerOk = false; - break; - } - } - - if (!PointerOk) + // If value V use is not dominating loop exit then promoting + // it may expose unsafe load and store instructions unconditinally. + if (PointerOk) + for(Value::use_iterator UI = V->use_begin(), UE = V->use_end(); + UI != UE && PointerOk; ++UI) { + Instruction *Use = dyn_cast(*UI); + if (!Use || !CurLoop->contains(Use->getParent())) + continue; + for (SmallVector::iterator + ExitI = LoopExits.begin(), ExitE = LoopExits.end(); + ExitI != ExitE; ++ExitI) { + Instruction *Ex = *ExitI; + if (!DT->dominates(Use, Ex)){ + PointerOk = false; break; + } } - } - + + if (!PointerOk) + break; + } + + if (PointerOk) { const Type *Ty = cast(V->getType())->getElementType(); AllocaInst *AI = new AllocaInst(Ty, 0, V->getName()+".tmp", FnStart); From djg at cray.com Tue Sep 25 11:23:27 2007 From: djg at cray.com (Dan Gohman) Date: Tue, 25 Sep 2007 18:23:27 -0000 Subject: [llvm-commits] [llvm] r42308 - in /llvm/trunk: lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/divrem.ll Message-ID: <200709251823.l8PINSHr021800@zion.cs.uiuc.edu> Author: djg Date: Tue Sep 25 13:23:27 2007 New Revision: 42308 URL: http://llvm.org/viewvc/llvm-project?rev=42308&view=rev Log: When both x/y and x%y are needed (x and y both scalar integer), compute both results with a single div or idiv instruction. This uses new X86ISD nodes for DIV and IDIV which are introduced during the legalize phase so that the SelectionDAG's CSE can automatically eliminate redundant computations. Added: llvm/trunk/test/CodeGen/X86/divrem.ll Modified: 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/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=42308&r1=42307&r2=42308&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Sep 25 13:23:27 2007 @@ -1162,12 +1162,9 @@ return NULL; } - case ISD::SDIV: - case ISD::UDIV: - case ISD::SREM: - case ISD::UREM: { - bool isSigned = Opcode == ISD::SDIV || Opcode == ISD::SREM; - bool isDiv = Opcode == ISD::SDIV || Opcode == ISD::UDIV; + case X86ISD::DIV: + case X86ISD::IDIV: { + bool isSigned = Opcode == X86ISD::IDIV; if (!isSigned) switch (NVT) { default: assert(0 && "Unsupported VT!"); @@ -1275,31 +1272,49 @@ SDOperand(CurDAG->getTargetNode(Opc, MVT::Flag, N1, InFlag), 0); } - unsigned Reg = isDiv ? LoReg : HiReg; - SDOperand Result; - if (Reg == 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, Reg, NVT, InFlag); + // 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); + 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 remainder (high) 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(Chain, X86::AX, MVT::i16, InFlag); + Chain = Result.getValue(1); + 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(Chain, HiReg, NVT, InFlag); + Chain = Result.getValue(1); + 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), Chain); #ifndef NDEBUG - DOUT << std::string(Indent-2, ' ') << "=> "; - DEBUG(Result.Val->dump(CurDAG)); - DOUT << "\n"; Indent -= 2; #endif Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=42308&r1=42307&r2=42308&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Sep 25 13:23:27 2007 @@ -155,6 +155,27 @@ 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); + setOperationAction(ISD::BR_JT , MVT::Other, Expand); setOperationAction(ISD::BRCOND , MVT::Other, Custom); setOperationAction(ISD::BR_CC , MVT::Other, Expand); @@ -3393,6 +3414,22 @@ 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 && @@ -4668,6 +4705,10 @@ 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); @@ -4751,6 +4792,8 @@ 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=42308&r1=42307&r2=42308&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Tue Sep 25 13:23:27 2007 @@ -181,6 +181,10 @@ /// in order to obtain suitable precision. FRSQRT, FRCP, + /// DIV, IDIV - Unsigned and signed integer division and reciprocal. + /// + DIV, IDIV, + // Thread Local Storage TLSADDR, THREAD_POINTER, @@ -420,6 +424,7 @@ 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); Added: llvm/trunk/test/CodeGen/X86/divrem.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/divrem.ll?rev=42308&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/divrem.ll (added) +++ llvm/trunk/test/CodeGen/X86/divrem.ll Tue Sep 25 13:23:27 2007 @@ -0,0 +1,58 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | grep div | count 8 + +define void @si64(i64 %x, i64 %y, i64* %p, i64* %q) { + %r = sdiv i64 %x, %y + %t = srem i64 %x, %y + store i64 %r, i64* %p + store i64 %t, i64* %q + ret void +} +define void @si32(i32 %x, i32 %y, i32* %p, i32* %q) { + %r = sdiv i32 %x, %y + %t = srem i32 %x, %y + store i32 %r, i32* %p + store i32 %t, i32* %q + ret void +} +define void @si16(i16 %x, i16 %y, i16* %p, i16* %q) { + %r = sdiv i16 %x, %y + %t = srem i16 %x, %y + store i16 %r, i16* %p + store i16 %t, i16* %q + ret void +} +define void @si8(i8 %x, i8 %y, i8* %p, i8* %q) { + %r = sdiv i8 %x, %y + %t = srem i8 %x, %y + store i8 %r, i8* %p + store i8 %t, i8* %q + ret void +} +define void @ui64(i64 %x, i64 %y, i64* %p, i64* %q) { + %r = udiv i64 %x, %y + %t = urem i64 %x, %y + store i64 %r, i64* %p + store i64 %t, i64* %q + ret void +} +define void @ui32(i32 %x, i32 %y, i32* %p, i32* %q) { + %r = udiv i32 %x, %y + %t = urem i32 %x, %y + store i32 %r, i32* %p + store i32 %t, i32* %q + ret void +} +define void @ui16(i16 %x, i16 %y, i16* %p, i16* %q) { + %r = udiv i16 %x, %y + %t = urem i16 %x, %y + store i16 %r, i16* %p + store i16 %t, i16* %q + ret void +} +define void @ui8(i8 %x, i8 %y, i8* %p, i8* %q) { + %r = udiv i8 %x, %y + %t = urem i8 %x, %y + store i8 %r, i8* %p + store i8 %t, i8* %q + ret void +} From dpatel at apple.com Tue Sep 25 11:24:49 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 25 Sep 2007 18:24:49 -0000 Subject: [llvm-commits] [llvm] r42309 - in /llvm/trunk: lib/Transforms/Scalar/LoopIndexSplit.cpp test/Transforms/LoopIndexSplit/2007-09-25-UpdateIterationSpace-2.ll Message-ID: <200709251824.l8PIOngn021863@zion.cs.uiuc.edu> Author: dpatel Date: Tue Sep 25 13:24:48 2007 New Revision: 42309 URL: http://llvm.org/viewvc/llvm-project?rev=42309&view=rev Log: Handle multiple induction variables. This fixes PR714. Added: llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-25-UpdateIterationSpace-2.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=42309&r1=42308&r2=42309&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Tue Sep 25 13:24:48 2007 @@ -676,7 +676,7 @@ continue; // Check if I is induction variable increment instruction. - if (!IndVarIncrement && I->getOpcode() == Instruction::Add) { + if (I->getOpcode() == Instruction::Add) { Value *Op0 = I->getOperand(0); Value *Op1 = I->getOperand(1); @@ -685,16 +685,23 @@ if ((PN = dyn_cast(Op0))) { if ((CI = dyn_cast(Op1))) - IndVarIncrement = I; + if (CI->isOne()) { + if (!IndVarIncrement && PN == IndVar) + IndVarIncrement = I; + // else this is another loop induction variable + continue; + } } else if ((PN = dyn_cast(Op1))) { if ((CI = dyn_cast(Op0))) - IndVarIncrement = I; + if (CI->isOne()) { + if (!IndVarIncrement && PN == IndVar) + IndVarIncrement = I; + // else this is another loop induction variable + continue; + } } - - if (IndVarIncrement && PN == IndVar && CI->isOne()) - continue; - } + } // I is an Exit condition if next instruction is block terminator. // Exit condition is OK if it compares loop invariant exit value, Added: llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-25-UpdateIterationSpace-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-25-UpdateIterationSpace-2.ll?rev=42309&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-25-UpdateIterationSpace-2.ll (added) +++ llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-25-UpdateIterationSpace-2.ll Tue Sep 25 13:24:48 2007 @@ -0,0 +1,59 @@ +; PR714 +; Update loop iteraton space to eliminate condition inside loop. +; RUN: llvm-as < %s | opt -loop-index-split | llvm-dis | not grep bothcond +define void @test(float* %x, i32 %ndat, float** %y, float %xcen, i32 %xmin, i32 %xmax, float %sigmal, float %contribution) { +entry: + %tmp5310 = icmp sgt i32 %xmin, %xmax ; [#uses=1] + br i1 %tmp5310, label %return, label %bb.preheader + +bb.preheader: ; preds = %entry + %tmp3031 = fpext float %contribution to double ; [#uses=1] + %tmp32 = mul double %tmp3031, 5.000000e-01 ; [#uses=1] + %tmp3839 = fpext float %sigmal to double ; [#uses=1] + br label %bb + +bb: ; preds = %bb.preheader, %cond_next45 + %i.01.0 = phi i32 [ %tmp47, %cond_next45 ], [ %xmin, %bb.preheader ] ; [#uses=4] + %k.06.0 = phi i32 [ %tmp49, %cond_next45 ], [ 0, %bb.preheader ] ; [#uses=3] + %tmp2 = icmp sgt i32 %i.01.0, -1 ; [#uses=1] + %tmp6 = icmp slt i32 %i.01.0, %ndat ; [#uses=1] + %bothcond = and i1 %tmp2, %tmp6 ; [#uses=1] + br i1 %bothcond, label %cond_true9, label %cond_next45 + +cond_true9: ; preds = %bb + %tmp12 = getelementptr float* %x, i32 %i.01.0 ; [#uses=1] + %tmp13 = load float* %tmp12, align 4 ; [#uses=1] + %tmp15 = sub float %xcen, %tmp13 ; [#uses=1] + %tmp16 = tail call float @fabsf( float %tmp15 ) ; [#uses=1] + %tmp18 = fdiv float %tmp16, %sigmal ; [#uses=1] + %tmp21 = load float** %y, align 4 ; [#uses=2] + %tmp27 = getelementptr float* %tmp21, i32 %k.06.0 ; [#uses=1] + %tmp28 = load float* %tmp27, align 4 ; [#uses=1] + %tmp2829 = fpext float %tmp28 to double ; [#uses=1] + %tmp34 = sub float -0.000000e+00, %tmp18 ; [#uses=1] + %tmp3435 = fpext float %tmp34 to double ; [#uses=1] + %tmp36 = tail call double @exp( double %tmp3435 ) ; [#uses=1] + %tmp37 = mul double %tmp32, %tmp36 ; [#uses=1] + %tmp40 = fdiv double %tmp37, %tmp3839 ; [#uses=1] + %tmp41 = add double %tmp2829, %tmp40 ; [#uses=1] + %tmp4142 = fptrunc double %tmp41 to float ; [#uses=1] + %tmp44 = getelementptr float* %tmp21, i32 %k.06.0 ; [#uses=1] + store float %tmp4142, float* %tmp44, align 4 + br label %cond_next45 + +cond_next45: ; preds = %bb, %cond_true9 + %tmp47 = add i32 %i.01.0, 1 ; [#uses=2] + %tmp49 = add i32 %k.06.0, 1 ; [#uses=1] + %tmp53 = icmp sgt i32 %tmp47, %xmax ; [#uses=1] + br i1 %tmp53, label %return.loopexit, label %bb + +return.loopexit: ; preds = %cond_next45 + br label %return + +return: ; preds = %return.loopexit, %entry + ret void +} + +declare float @fabsf(float) + +declare double @exp(double) From evan.cheng at apple.com Tue Sep 25 11:29:54 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 Sep 2007 11:29:54 -0700 Subject: [llvm-commits] [llvm] r42308 - in /llvm/trunk: lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/divrem.ll In-Reply-To: <200709251823.l8PINSHr021800@zion.cs.uiuc.edu> References: <200709251823.l8PINSHr021800@zion.cs.uiuc.edu> Message-ID: <74FEA482-FCAC-40A1-9121-4D14E016E872@apple.com> Yay! :-) On Sep 25, 2007, at 11:23 AM, Dan Gohman wrote: > Author: djg > Date: Tue Sep 25 13:23:27 2007 > New Revision: 42308 > > URL: http://llvm.org/viewvc/llvm-project?rev=42308&view=rev > Log: > When both x/y and x%y are needed (x and y both scalar integer), > compute > both results with a single div or idiv instruction. This uses new > X86ISD > nodes for DIV and IDIV which are introduced during the legalize phase > so that the SelectionDAG's CSE can automatically eliminate redundant > computations. > > Added: > llvm/trunk/test/CodeGen/X86/divrem.ll > Modified: > 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/Target/X86/X86ISelDAGToDAG.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/ > X86ISelDAGToDAG.cpp?rev=42308&r1=42307&r2=42308&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Sep 25 > 13:23:27 2007 > @@ -1162,12 +1162,9 @@ > return NULL; > } > > - case ISD::SDIV: > - case ISD::UDIV: > - case ISD::SREM: > - case ISD::UREM: { > - bool isSigned = Opcode == ISD::SDIV || Opcode == ISD::SREM; > - bool isDiv = Opcode == ISD::SDIV || Opcode == ISD::UDIV; > + case X86ISD::DIV: > + case X86ISD::IDIV: { > + bool isSigned = Opcode == X86ISD::IDIV; > if (!isSigned) > switch (NVT) { > default: assert(0 && "Unsupported VT!"); > @@ -1275,31 +1272,49 @@ > SDOperand(CurDAG->getTargetNode(Opc, MVT::Flag, N1, > InFlag), 0); > } > > - unsigned Reg = isDiv ? LoReg : HiReg; > - SDOperand Result; > - if (Reg == 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, Reg, NVT, InFlag); > + // 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); > + 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 remainder (high) 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(Chain, X86::AX, > MVT::i16, InFlag); > + Chain = Result.getValue(1); > + 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(Chain, HiReg, NVT, InFlag); > + Chain = Result.getValue(1); > + 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), Chain); > > #ifndef NDEBUG > - DOUT << std::string(Indent-2, ' ') << "=> "; > - DEBUG(Result.Val->dump(CurDAG)); > - DOUT << "\n"; > Indent -= 2; > #endif > > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/ > X86ISelLowering.cpp?rev=42308&r1=42307&r2=42308&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Sep 25 > 13:23:27 2007 > @@ -155,6 +155,27 @@ > 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); > + > setOperationAction(ISD::BR_JT , MVT::Other, Expand); > setOperationAction(ISD::BRCOND , MVT::Other, Custom); > setOperationAction(ISD::BR_CC , MVT::Other, Expand); > @@ -3393,6 +3414,22 @@ > 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 && > @@ -4668,6 +4705,10 @@ > 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); > @@ -4751,6 +4792,8 @@ > 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=42308&r1=42307&r2=42308&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Tue Sep 25 13:23:27 > 2007 > @@ -181,6 +181,10 @@ > /// in order to obtain suitable precision. > FRSQRT, FRCP, > > + /// DIV, IDIV - Unsigned and signed integer division and > reciprocal. > + /// > + DIV, IDIV, > + > // Thread Local Storage > TLSADDR, THREAD_POINTER, > > @@ -420,6 +424,7 @@ > 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); > > Added: llvm/trunk/test/CodeGen/X86/divrem.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ > X86/divrem.ll?rev=42308&view=auto > > ====================================================================== > ======== > --- llvm/trunk/test/CodeGen/X86/divrem.ll (added) > +++ llvm/trunk/test/CodeGen/X86/divrem.ll Tue Sep 25 13:23:27 2007 > @@ -0,0 +1,58 @@ > +; RUN: llvm-as < %s | llc -march=x86-64 | grep div | count 8 > + > +define void @si64(i64 %x, i64 %y, i64* %p, i64* %q) { > + %r = sdiv i64 %x, %y > + %t = srem i64 %x, %y > + store i64 %r, i64* %p > + store i64 %t, i64* %q > + ret void > +} > +define void @si32(i32 %x, i32 %y, i32* %p, i32* %q) { > + %r = sdiv i32 %x, %y > + %t = srem i32 %x, %y > + store i32 %r, i32* %p > + store i32 %t, i32* %q > + ret void > +} > +define void @si16(i16 %x, i16 %y, i16* %p, i16* %q) { > + %r = sdiv i16 %x, %y > + %t = srem i16 %x, %y > + store i16 %r, i16* %p > + store i16 %t, i16* %q > + ret void > +} > +define void @si8(i8 %x, i8 %y, i8* %p, i8* %q) { > + %r = sdiv i8 %x, %y > + %t = srem i8 %x, %y > + store i8 %r, i8* %p > + store i8 %t, i8* %q > + ret void > +} > +define void @ui64(i64 %x, i64 %y, i64* %p, i64* %q) { > + %r = udiv i64 %x, %y > + %t = urem i64 %x, %y > + store i64 %r, i64* %p > + store i64 %t, i64* %q > + ret void > +} > +define void @ui32(i32 %x, i32 %y, i32* %p, i32* %q) { > + %r = udiv i32 %x, %y > + %t = urem i32 %x, %y > + store i32 %r, i32* %p > + store i32 %t, i32* %q > + ret void > +} > +define void @ui16(i16 %x, i16 %y, i16* %p, i16* %q) { > + %r = udiv i16 %x, %y > + %t = urem i16 %x, %y > + store i16 %r, i16* %p > + store i16 %t, i16* %q > + ret void > +} > +define void @ui8(i8 %x, i8 %y, i8* %p, i8* %q) { > + %r = udiv i8 %x, %y > + %t = urem i8 %x, %y > + store i8 %r, i8* %p > + store i8 %t, i8* %q > + ret void > +} > > > _______________________________________________ > 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 Tue Sep 25 12:08:03 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 Sep 2007 19:08:03 -0000 Subject: [llvm-commits] [llvm] r42312 - in /llvm/trunk/lib/Target/X86: X86FloatingPoint.cpp X86InstrFPStack.td Message-ID: <200709251908.l8PJ83Ig023410@zion.cs.uiuc.edu> Author: evancheng Date: Tue Sep 25 14:08:02 2007 New Revision: 42312 URL: http://llvm.org/viewvc/llvm-project?rev=42312&view=rev Log: New style x87 cmp instructions. Modified: llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp llvm/trunk/lib/Target/X86/X86InstrFPStack.td Modified: llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp?rev=42312&r1=42311&r2=42312&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp Tue Sep 25 14:08:02 2007 @@ -463,6 +463,12 @@ { X86::NEW_CMOVP_Fp32 , X86::CMOVP_F }, { X86::NEW_CMOVP_Fp64 , X86::CMOVP_F }, { X86::NEW_CMOVP_Fp80 , X86::CMOVP_F }, + { X86::NEW_UCOM_FpIr32 , X86::UCOM_FIr }, + { X86::NEW_UCOM_FpIr64 , X86::UCOM_FIr }, + { X86::NEW_UCOM_FpIr80 , X86::UCOM_FIr }, + { X86::NEW_UCOM_Fpr32 , X86::UCOM_Fr }, + { X86::NEW_UCOM_Fpr64 , X86::UCOM_Fr }, + { X86::NEW_UCOM_Fpr80 , X86::UCOM_Fr }, { X86::SIN_Fp32 , X86::SIN_F }, { X86::SIN_Fp64 , X86::SIN_F }, Modified: llvm/trunk/lib/Target/X86/X86InstrFPStack.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFPStack.td?rev=42312&r1=42311&r2=42312&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrFPStack.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrFPStack.td Tue Sep 25 14:08:02 2007 @@ -503,6 +503,7 @@ // Floating point compares. +let Defs = [EFLAGS] in { def UCOM_Fpr32 : FpIf32<(outs), (ins RFP32:$lhs, RFP32:$rhs), CompareFP, []>; // FPSW = cmp ST(0) with ST(i) def UCOM_FpIr32: FpIf32<(outs), (ins RFP32:$lhs, RFP32:$rhs), CompareFP, @@ -516,6 +517,23 @@ def UCOM_FpIr80: FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, [(X86cmp RFP80:$lhs, RFP80:$rhs)]>; // CC = ST(0) cmp ST(i) +def NEW_UCOM_Fpr32 : FpIf32<(outs), (ins RFP32:$lhs, RFP32:$rhs), CompareFP, + []>; // FPSW = cmp ST(0) with ST(i) +def NEW_UCOM_FpIr32: FpIf32<(outs), (ins RFP32:$lhs, RFP32:$rhs), CompareFP, + [(X86cmp_new RFP32:$lhs, RFP32:$rhs), + (implicit EFLAGS)]>; // CC = ST(0) cmp ST(i) +def NEW_UCOM_Fpr64 : FpIf64<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, + []>; // FPSW = cmp ST(0) with ST(i) +def NEW_UCOM_FpIr64: FpIf64<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, + [(X86cmp_new RFP64:$lhs, RFP64:$rhs), + (implicit EFLAGS)]>; // CC = ST(0) cmp ST(i) +def NEW_UCOM_Fpr80 : FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, + []>; // FPSW = cmp ST(0) with ST(i) +def NEW_UCOM_FpIr80: FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, + [(X86cmp_new RFP80:$lhs, RFP80:$rhs), + (implicit EFLAGS)]>; // CC = ST(0) cmp ST(i) +} + let Defs = [EFLAGS], Uses = [ST0] in { def UCOM_Fr : FPI<0xE0, AddRegFrm, // FPSW = cmp ST(0) with ST(i) (outs), (ins RST:$reg), From djg at cray.com Tue Sep 25 12:37:26 2007 From: djg at cray.com (Dan Gohman) Date: Tue, 25 Sep 2007 19:37:26 -0000 Subject: [llvm-commits] [llvm] r42313 - /llvm/trunk/lib/Target/X86/X86ISelLowering.h Message-ID: <200709251937.l8PJbQqO024760@zion.cs.uiuc.edu> Author: djg Date: Tue Sep 25 14:37:26 2007 New Revision: 42313 URL: http://llvm.org/viewvc/llvm-project?rev=42313&view=rev Log: Fix a typo in a comment. 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=42313&r1=42312&r2=42313&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Tue Sep 25 14:37:26 2007 @@ -181,7 +181,7 @@ /// in order to obtain suitable precision. FRSQRT, FRCP, - /// DIV, IDIV - Unsigned and signed integer division and reciprocal. + /// DIV, IDIV - Unsigned and signed integer division and remainder. /// DIV, IDIV, From baldrick at free.fr Tue Sep 25 13:08:48 2007 From: baldrick at free.fr (Duncan Sands) Date: Tue, 25 Sep 2007 20:08:48 -0000 Subject: [llvm-commits] [llvm] r42314 - /llvm/trunk/lib/Analysis/PostDominatorCalculation.h Message-ID: <200709252008.l8PK8mKX026054@zion.cs.uiuc.edu> Author: baldrick Date: Tue Sep 25 15:08:48 2007 New Revision: 42314 URL: http://llvm.org/viewvc/llvm-project?rev=42314&view=rev Log: Add a newline to the end of this file. Modified: llvm/trunk/lib/Analysis/PostDominatorCalculation.h Modified: llvm/trunk/lib/Analysis/PostDominatorCalculation.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PostDominatorCalculation.h?rev=42314&r1=42313&r2=42314&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PostDominatorCalculation.h (original) +++ llvm/trunk/lib/Analysis/PostDominatorCalculation.h Tue Sep 25 15:08:48 2007 @@ -112,4 +112,4 @@ } } -#endif \ No newline at end of file +#endif From baldrick at free.fr Tue Sep 25 13:12:14 2007 From: baldrick at free.fr (Duncan Sands) Date: Tue, 25 Sep 2007 20:12:14 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r42315 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200709252012.l8PKCEfk026168@zion.cs.uiuc.edu> Author: baldrick Date: Tue Sep 25 15:12:14 2007 New Revision: 42315 URL: http://llvm.org/viewvc/llvm-project?rev=42315&view=rev Log: Handle scalar to aggregate VIEW_CONVERT_EXPR lvalue. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=42315&r1=42314&r2=42315&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Sep 25 15:12:14 2007 @@ -5068,12 +5068,22 @@ } LValue TreeToLLVM::EmitLV_VIEW_CONVERT_EXPR(tree exp) { - // The address is the address of the operand. - LValue LV = EmitLV(TREE_OPERAND(exp, 0)); - // The type is the type of the expression. - const Type *Ty = ConvertType(TREE_TYPE(exp)); - LV.Ptr = BitCastToType(LV.Ptr, PointerType::get(Ty)); - return LV; + tree Op = TREE_OPERAND(exp, 0); + + if (isAggregateTreeType(TREE_TYPE(Op))) { + // If the input is an aggregate, the address is the address of the operand. + LValue LV = EmitLV(Op); + // The type is the type of the expression. + LV.Ptr = BitCastToType(LV.Ptr, PointerType::get(ConvertType(TREE_TYPE(exp)))); + return LV; + } else { + // If the input is a scalar, emit to a temporary. + Value *Dest = CreateTemporary(ConvertType(TREE_TYPE(Op))); + Builder.CreateStore(Emit(Op, 0), Dest); + // The type is the type of the expression. + Dest = BitCastToType(Dest, PointerType::get(ConvertType(TREE_TYPE(exp)))); + return LValue(Dest); + } } LValue TreeToLLVM::EmitLV_EXC_PTR_EXPR(tree exp) { From djg at cray.com Tue Sep 25 13:27:06 2007 From: djg at cray.com (Dan Gohman) Date: Tue, 25 Sep 2007 20:27:06 -0000 Subject: [llvm-commits] [llvm] r42316 - in /llvm/trunk/lib/Target: ARM/ARMTargetAsmInfo.h Alpha/AlphaTargetAsmInfo.h IA64/IA64TargetAsmInfo.h Mips/MipsTargetAsmInfo.h PowerPC/PPCTargetAsmInfo.h Sparc/SparcTargetAsmInfo.h X86/X86TargetAsmInfo.h Message-ID: <200709252027.l8PKR6TZ026715@zion.cs.uiuc.edu> Author: djg Date: Tue Sep 25 15:27:06 2007 New Revision: 42316 URL: http://llvm.org/viewvc/llvm-project?rev=42316&view=rev Log: More explicit keywords. Modified: llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.h llvm/trunk/lib/Target/Alpha/AlphaTargetAsmInfo.h llvm/trunk/lib/Target/IA64/IA64TargetAsmInfo.h llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.h llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.h llvm/trunk/lib/Target/Sparc/SparcTargetAsmInfo.h llvm/trunk/lib/Target/X86/X86TargetAsmInfo.h Modified: llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.h?rev=42316&r1=42315&r2=42316&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.h Tue Sep 25 15:27:06 2007 @@ -23,7 +23,7 @@ class ARMTargetMachine; struct ARMTargetAsmInfo : public TargetAsmInfo { - ARMTargetAsmInfo(const ARMTargetMachine &TM); + explicit ARMTargetAsmInfo(const ARMTargetMachine &TM); const ARMSubtarget *Subtarget; Modified: llvm/trunk/lib/Target/Alpha/AlphaTargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaTargetAsmInfo.h?rev=42316&r1=42315&r2=42316&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaTargetAsmInfo.h (original) +++ llvm/trunk/lib/Target/Alpha/AlphaTargetAsmInfo.h Tue Sep 25 15:27:06 2007 @@ -22,7 +22,7 @@ class AlphaTargetMachine; struct AlphaTargetAsmInfo : public TargetAsmInfo { - AlphaTargetAsmInfo(const AlphaTargetMachine &TM); + explicit AlphaTargetAsmInfo(const AlphaTargetMachine &TM); }; } // namespace llvm Modified: llvm/trunk/lib/Target/IA64/IA64TargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64TargetAsmInfo.h?rev=42316&r1=42315&r2=42316&view=diff ============================================================================== --- llvm/trunk/lib/Target/IA64/IA64TargetAsmInfo.h (original) +++ llvm/trunk/lib/Target/IA64/IA64TargetAsmInfo.h Tue Sep 25 15:27:06 2007 @@ -22,7 +22,7 @@ class IA64TargetMachine; struct IA64TargetAsmInfo : public TargetAsmInfo { - IA64TargetAsmInfo(const IA64TargetMachine &TM); + explicit IA64TargetAsmInfo(const IA64TargetMachine &TM); }; Modified: llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.h?rev=42316&r1=42315&r2=42316&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.h (original) +++ llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.h Tue Sep 25 15:27:06 2007 @@ -22,7 +22,7 @@ class MipsTargetMachine; struct MipsTargetAsmInfo : public TargetAsmInfo { - MipsTargetAsmInfo(const MipsTargetMachine &TM); + explicit MipsTargetAsmInfo(const MipsTargetMachine &TM); }; } // namespace llvm Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.h?rev=42316&r1=42315&r2=42316&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.h Tue Sep 25 15:27:06 2007 @@ -22,15 +22,15 @@ class PPCTargetMachine; struct PPCTargetAsmInfo : public TargetAsmInfo { - PPCTargetAsmInfo(const PPCTargetMachine &TM); + explicit PPCTargetAsmInfo(const PPCTargetMachine &TM); }; struct DarwinTargetAsmInfo : public PPCTargetAsmInfo { - DarwinTargetAsmInfo(const PPCTargetMachine &TM); + explicit DarwinTargetAsmInfo(const PPCTargetMachine &TM); }; struct LinuxTargetAsmInfo : public PPCTargetAsmInfo { - LinuxTargetAsmInfo(const PPCTargetMachine &TM); + explicit LinuxTargetAsmInfo(const PPCTargetMachine &TM); }; } // namespace llvm Modified: llvm/trunk/lib/Target/Sparc/SparcTargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcTargetAsmInfo.h?rev=42316&r1=42315&r2=42316&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcTargetAsmInfo.h (original) +++ llvm/trunk/lib/Target/Sparc/SparcTargetAsmInfo.h Tue Sep 25 15:27:06 2007 @@ -22,7 +22,7 @@ class SparcTargetMachine; struct SparcTargetAsmInfo : public TargetAsmInfo { - SparcTargetAsmInfo(const SparcTargetMachine &TM); + explicit SparcTargetAsmInfo(const SparcTargetMachine &TM); }; Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetAsmInfo.h?rev=42316&r1=42315&r2=42316&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86TargetAsmInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86TargetAsmInfo.h Tue Sep 25 15:27:06 2007 @@ -22,7 +22,7 @@ class X86TargetMachine; struct X86TargetAsmInfo : public TargetAsmInfo { - X86TargetAsmInfo(const X86TargetMachine &TM); + explicit X86TargetAsmInfo(const X86TargetMachine &TM); virtual bool ExpandInlineAsm(CallInst *CI) const; private: From isanbard at gmail.com Tue Sep 25 13:45:10 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Sep 2007 20:45:10 -0000 Subject: [llvm-commits] [llvm] r42318 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <200709252045.l8PKjAlc027280@zion.cs.uiuc.edu> Author: void Date: Tue Sep 25 15:45:10 2007 New Revision: 42318 URL: http://llvm.org/viewvc/llvm-project?rev=42318&view=rev Log: Grammar fix. Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=42318&r1=42317&r2=42318&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Tue Sep 25 15:45:10 2007 @@ -313,7 +313,7 @@ components, please contact us on the LLVMdev list.

        -
      • The -cee pass is known to be buggy, and may be removed in in a +
      • The -cee pass is known to be buggy, and may be removed in a future release.
      • C++ EH support is disabled for this release.
      • The MSIL backend is experimental.
      • From clattner at apple.com Tue Sep 25 13:49:50 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 25 Sep 2007 13:49:50 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r42315 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <200709252012.l8PKCEfk026168@zion.cs.uiuc.edu> References: <200709252012.l8PKCEfk026168@zion.cs.uiuc.edu> Message-ID: This should also be safe to apply to 4.0, right? -Chris On Sep 25, 2007, at 1:12 PM, Duncan Sands wrote: > Author: baldrick > Date: Tue Sep 25 15:12:14 2007 > New Revision: 42315 > > URL: http://llvm.org/viewvc/llvm-project?rev=42315&view=rev > Log: > Handle scalar to aggregate VIEW_CONVERT_EXPR lvalue. > > Modified: > llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp > > Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ > llvm-convert.cpp?rev=42315&r1=42314&r2=42315&view=diff > > ====================================================================== > ======== > --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) > +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Sep 25 15:12:14 2007 > @@ -5068,12 +5068,22 @@ > } > > LValue TreeToLLVM::EmitLV_VIEW_CONVERT_EXPR(tree exp) { > - // The address is the address of the operand. > - LValue LV = EmitLV(TREE_OPERAND(exp, 0)); > - // The type is the type of the expression. > - const Type *Ty = ConvertType(TREE_TYPE(exp)); > - LV.Ptr = BitCastToType(LV.Ptr, PointerType::get(Ty)); > - return LV; > + tree Op = TREE_OPERAND(exp, 0); > + > + if (isAggregateTreeType(TREE_TYPE(Op))) { > + // If the input is an aggregate, the address is the address of > the operand. > + LValue LV = EmitLV(Op); > + // The type is the type of the expression. > + LV.Ptr = BitCastToType(LV.Ptr, PointerType::get(ConvertType > (TREE_TYPE(exp)))); > + return LV; > + } else { > + // If the input is a scalar, emit to a temporary. > + Value *Dest = CreateTemporary(ConvertType(TREE_TYPE(Op))); > + Builder.CreateStore(Emit(Op, 0), Dest); > + // The type is the type of the expression. > + Dest = BitCastToType(Dest, PointerType::get(ConvertType > (TREE_TYPE(exp)))); > + return LValue(Dest); > + } > } > > LValue TreeToLLVM::EmitLV_EXC_PTR_EXPR(tree exp) { > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From tonic at nondot.org Tue Sep 25 14:20:43 2007 From: tonic at nondot.org (Tanya Lattner) Date: Tue, 25 Sep 2007 21:20:43 -0000 Subject: [llvm-commits] [test-suite] r42321 - in /test-suite/trunk/SingleSource/Regression/C++: ofstream_ctor.cpp short_circuit_dtor.cpp Message-ID: <200709252120.l8PLKh4B028397@zion.cs.uiuc.edu> Author: tbrethou Date: Tue Sep 25 16:20:42 2007 New Revision: 42321 URL: http://llvm.org/viewvc/llvm-project?rev=42321&view=rev Log: Test cases should return 0. Modified: test-suite/trunk/SingleSource/Regression/C++/ofstream_ctor.cpp test-suite/trunk/SingleSource/Regression/C++/short_circuit_dtor.cpp Modified: test-suite/trunk/SingleSource/Regression/C++/ofstream_ctor.cpp URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Regression/C%2B%2B/ofstream_ctor.cpp?rev=42321&r1=42320&r2=42321&view=diff ============================================================================== --- test-suite/trunk/SingleSource/Regression/C++/ofstream_ctor.cpp (original) +++ test-suite/trunk/SingleSource/Regression/C++/ofstream_ctor.cpp Tue Sep 25 16:20:42 2007 @@ -2,5 +2,6 @@ #include int main() { std::ofstream X; + return 0; } Modified: test-suite/trunk/SingleSource/Regression/C++/short_circuit_dtor.cpp URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Regression/C%2B%2B/short_circuit_dtor.cpp?rev=42321&r1=42320&r2=42321&view=diff ============================================================================== --- test-suite/trunk/SingleSource/Regression/C++/short_circuit_dtor.cpp (original) +++ test-suite/trunk/SingleSource/Regression/C++/short_circuit_dtor.cpp Tue Sep 25 16:20:42 2007 @@ -11,4 +11,5 @@ int main() { if ((foo(1) || foo(2))) bar(); + return 0; } From clattner at apple.com Tue Sep 25 14:21:25 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 25 Sep 2007 14:21:25 -0700 Subject: [llvm-commits] [llvm] r42308 - in /llvm/trunk: lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/divrem.ll In-Reply-To: <200709251823.l8PINSHr021800@zion.cs.uiuc.edu> References: <200709251823.l8PINSHr021800@zion.cs.uiuc.edu> Message-ID: <2F34B541-991A-4F06-9A08-886D88100129@apple.com> > URL: http://llvm.org/viewvc/llvm-project?rev=42308&view=rev > Log: > When both x/y and x%y are needed (x and y both scalar integer), > compute > both results with a single div or idiv instruction. This uses new > X86ISD > nodes for DIV and IDIV which are introduced during the legalize phase > so that the SelectionDAG's CSE can automatically eliminate redundant > computations. Very nice. Would it make sense to make this be a target independent node? It seems like other chips have similar divide instructions, though I can't recall any off-hand. This would also help with the standard problem of target-specific nodes blocking the target- independent dag combiner. If you're interested in this area, another big potential win is for long multiplies. The ARM backend currently has these two target- specific nodes: MULHILOU, // Lo,Hi = umul LHS, RHS. MULHILOS, // Lo,Hi = smul LHS, RHS. It has been on my todo list forever to merge these (and the logic in ARMISelLowering.cpp:LowerMUL) up to target-independent code. This would allow the X86 backend to use it, getting better wide multiplies. -Chris From clattner at apple.com Tue Sep 25 14:29:16 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 25 Sep 2007 14:29:16 -0700 Subject: [llvm-commits] [llvm-gcc-4.0] r42287 - in /llvm-gcc-4.0/trunk/gcc: c-common.h llvm-backend.cpp objc/objc-act.c stub-objc.c In-Reply-To: <200709250251.l8P2pI2f010914@zion.cs.uiuc.edu> References: <200709250251.l8P2pI2f010914@zion.cs.uiuc.edu> Message-ID: On Sep 24, 2007, at 7:51 PM, Bill Wendling wrote: > URL: http://llvm.org/viewvc/llvm-project?rev=42287&view=rev > Log: > During the processing of Objective-C "protocols", the objc frontend > creates two > decls for the protocol. One for the metadata and another for when it's > referenced. However, protocols are "internal global", so when we do > a lookup > for the reference, it doesn't find the first decl because it's not > "external". > This will perform a second lookup for objective C protocols if we > don't find > it among the "external globals". Hi Bill, This is a good short-term solution Bill, but I don't think it is what we want to keep. Specifically, your new function adds a fairly expensive call to strstr to the global variable emission path for all languages. It would be better to merge the vardecls in objc-act.c where it creates them. I see this code: /* Build decl = initializer; for each protocol referenced in @protocol (MyProtole) expression. */ static void build_protocollist_translation_table (void) { tree chain; static char string[BUFSIZE]; for (chain = protocollist_ref_chain; chain; chain = TREE_CHAIN (chain)) { tree expr = TREE_VALUE (chain); tree decl = TREE_PURPOSE (chain); gcc_assert (TREE_CODE (expr) == PROTOCOL_INTERFACE_TYPE); /* APPLE LOCAL begin radar 4695109 */ sprintf (string, "_OBJC_PROTOCOL_$_%s", IDENTIFIER_POINTER (PROTOCOL_NAME (expr))); expr = start_var_decl (objc_v2_protocol_template, string); /* APPLE LOCAL end radar 4695109 */ expr = convert (objc_protocol_type, build_fold_addr_expr (expr)); finish_var_decl (decl, expr); } } and this: static void build_v2_protocol_reference (tree p) { tree decl; const char *proto_name; /* static struct protocol_t _OBJC_PROTOCOL_$; */ proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_$", p); decl = start_var_decl (objc_v2_protocol_template, proto_name); PROTOCOL_V2_FORWARD_DECL (p) = decl; } I'm not sure which happens first, but this is creating two DECL nodes with the same name. Can you please investigate using lookup_name to only create the new var_decl node if it doesn't already exist? It might just be a matter of changing the code to looks like this: proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_$", p); if ((decl = lookup_name(proto_name)) == 0) decl = start_var_decl (objc_v2_protocol_template, proto_name); PROTOCOL_V2_FORWARD_DECL (p) = decl; Or something. -Chris > Modified: > llvm-gcc-4.0/trunk/gcc/c-common.h > llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp > llvm-gcc-4.0/trunk/gcc/objc/objc-act.c > llvm-gcc-4.0/trunk/gcc/stub-objc.c > > Modified: llvm-gcc-4.0/trunk/gcc/c-common.h > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/c- > common.h?rev=42287&r1=42286&r2=42287&view=diff > > ====================================================================== > ======== > --- llvm-gcc-4.0/trunk/gcc/c-common.h (original) > +++ llvm-gcc-4.0/trunk/gcc/c-common.h Mon Sep 24 21:51:18 2007 > @@ -1139,6 +1139,12 @@ > extern void objc_remove_weak_read (tree*); > /* APPLE LOCAL end radar 4426814 */ > > +/* APPLE LOCAL begin - LLVM radar 5476262 */ > +#ifdef ENABLE_LLVM > +extern bool objc_is_protocol_reference (const char *name); > +#endif > +/* APPLE LOCAL end - LLVM radar 5476262 */ > + > /* APPLE LOCAL begin C* language */ > extern void objc_set_method_opt (int); > void objc_finish_foreach_loop (location_t, tree, tree, tree, tree); > > Modified: llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/ > llvm-backend.cpp?rev=42287&r1=42286&r2=42287&view=diff > > ====================================================================== > ======== > --- llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp (original) > +++ llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Mon Sep 24 21:51:18 2007 > @@ -66,6 +66,7 @@ > #include "function.h" > #include "tree-inline.h" > #include "langhooks.h" > +#include "c-common.h" > } > > // Non-zero if bytecode from PCH is successfully read. > @@ -1060,6 +1061,14 @@ > // If the global has a name, prevent multiple vars with the > same name from > // being created. > GlobalVariable *GVE = TheModule->getGlobalVariable(Name); > + > + // And Objective-C "@protocol" will create a decl for the > + // protocol metadata and then when the protocol is > + // referenced. However, protocols have file-scope, so they > + // aren't found in the GlobalVariable list unless we look at > + // non-extern globals as well. > + if (!GVE && c_dialect_objc() && objc_is_protocol_reference > (Name)) > + GVE = TheModule->getGlobalVariable(Name, true); > > if (GVE == 0) { > GV = new GlobalVariable(Ty, false, > GlobalValue::ExternalLinkage,0, > > 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=42287&r1=42286&r2=42287&view=diff > > ====================================================================== > ======== > --- llvm-gcc-4.0/trunk/gcc/objc/objc-act.c (original) > +++ llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Mon Sep 24 21:51:18 2007 > @@ -11669,6 +11669,19 @@ > } > } > > +/* APPLE LOCAL begin - LLVM radar 5476262 */ > +#ifdef ENABLE_LLVM > +/* This routine returns true if the name is the same as a protocol > + reference name. */ > + > +bool > +objc_is_protocol_reference (const char *name) > +{ > + return flag_objc_abi == 2 && strstr (name, "_OBJC_PROTOCOL_$_") ! > = 0; > +} > +#endif > +/* APPLE LOCAL end - LLVM radar 5476262 */ > + > /* This routine builds the protocol_reference_chain for each > protocol name used > @protocol(MyProtocol) expression. IDENT is current protocol > name. */ > > > Modified: llvm-gcc-4.0/trunk/gcc/stub-objc.c > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/ > stub-objc.c?rev=42287&r1=42286&r2=42287&view=diff > > ====================================================================== > ======== > --- llvm-gcc-4.0/trunk/gcc/stub-objc.c (original) > +++ llvm-gcc-4.0/trunk/gcc/stub-objc.c Mon Sep 24 21:51:18 2007 > @@ -548,3 +548,13 @@ > return false; > } > /* APPLE LOCAL end radar 4985544 */ > + > +/* APPLE LOCAL begin - LLVM radar 5476262 */ > +#ifdef ENABLE_LLVM > +bool > +objc_is_protocol_reference (const char * ARG_UNUSED(name)) > +{ > + return false; > +} > +#endif > +/* APPLE LOCAL end - LLVM radar 5476262 */ > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Tue Sep 25 14:38:34 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Sep 2007 14:38:34 -0700 Subject: [llvm-commits] [llvm-gcc-4.0] r42287 - in /llvm-gcc-4.0/trunk/gcc: c-common.h llvm-backend.cpp objc/objc-act.c stub-objc.c In-Reply-To: References: <200709250251.l8P2pI2f010914@zion.cs.uiuc.edu> Message-ID: <16e5fdf90709251438t564b51d4n62e06483c5deb9c8@mail.gmail.com> On 9/25/07, Chris Lattner wrote: > On Sep 24, 2007, at 7:51 PM, Bill Wendling wrote: > > URL: http://llvm.org/viewvc/llvm-project?rev=42287&view=rev > > Log: > > During the processing of Objective-C "protocols", the objc frontend > > creates two > > decls for the protocol. One for the metadata and another for when it's > > referenced. However, protocols are "internal global", so when we do > > a lookup > > for the reference, it doesn't find the first decl because it's not > > "external". > > This will perform a second lookup for objective C protocols if we > > don't find > > it among the "external globals". > > Hi Bill, > > This is a good short-term solution Bill, but I don't think it is what > we want to keep. > I agree. > Specifically, your new function adds a fairly expensive call to > strstr to the global variable emission path for all languages. > It only does the check if this is objc. And further limits it in the function call itself to only objc-2. I tried to limit it as much as possible. :-) > It would be better to merge the vardecls in objc-act.c where it > creates them. I see this code: > > /* Build decl = initializer; for each protocol referenced in @protocol > (MyProtole) expression. */ > > static void > build_protocollist_translation_table (void) > { > tree chain; > static char string[BUFSIZE]; > > for (chain = protocollist_ref_chain; chain; chain = TREE_CHAIN > (chain)) > { > tree expr = TREE_VALUE (chain); > tree decl = TREE_PURPOSE (chain); > gcc_assert (TREE_CODE (expr) == PROTOCOL_INTERFACE_TYPE); > /* APPLE LOCAL begin radar 4695109 */ > sprintf (string, "_OBJC_PROTOCOL_$_%s", > IDENTIFIER_POINTER (PROTOCOL_NAME (expr))); > expr = start_var_decl (objc_v2_protocol_template, string); > /* APPLE LOCAL end radar 4695109 */ > expr = convert (objc_protocol_type, build_fold_addr_expr (expr)); > finish_var_decl (decl, expr); > } > } > > and this: > > static void > build_v2_protocol_reference (tree p) > { > tree decl; > const char *proto_name; > > /* static struct protocol_t _OBJC_PROTOCOL_$; */ > > proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_$", p); > decl = start_var_decl (objc_v2_protocol_template, proto_name); > PROTOCOL_V2_FORWARD_DECL (p) = decl; > } > > I'm not sure which happens first, but this is creating two DECL nodes > with the same name. I believe that "build_protocollist_translation_table ()" is called last. > Can you please investigate using lookup_name to > only create the new var_decl node if it doesn't already exist? > > It might just be a matter of changing the code to looks like this: > > proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_$", p); > if ((decl = lookup_name(proto_name)) == 0) > decl = start_var_decl (objc_v2_protocol_template, proto_name); > PROTOCOL_V2_FORWARD_DECL (p) = decl; > > Or something. > You read my mind! :-) I'm testing something akin to this right now, actually. I'll let you know how it goes. -bw From asl at math.spbu.ru Tue Sep 25 14:52:30 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Tue, 25 Sep 2007 21:52:30 -0000 Subject: [llvm-commits] [llvm] r42322 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200709252152.l8PLqUrX029594@zion.cs.uiuc.edu> Author: asl Date: Tue Sep 25 16:52:30 2007 New Revision: 42322 URL: http://llvm.org/viewvc/llvm-project?rev=42322&view=rev Log: Partly revert invalid r41774 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=42322&r1=42321&r2=42322&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Sep 25 16:52:30 2007 @@ -130,6 +130,8 @@ /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); + virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF); + virtual bool CanBeFoldedBy(SDNode *N, SDNode *U, SDNode *Root) const; // Include the pieces autogenerated from the target description. @@ -162,6 +164,8 @@ std::vector &OutOps, SelectionDAG &DAG); + void EmitSpecialCodeForMain(MachineBasicBlock *BB, MachineFrameInfo *MFI); + inline void getAddressOperands(X86ISelAddressMode &AM, SDOperand &Base, SDOperand &Scale, SDOperand &Index, SDOperand &Disp) { @@ -540,6 +544,22 @@ } while (&*(MBBI++) != BB); } +/// EmitSpecialCodeForMain - Emit any code that needs to be executed only in +/// the main function. +void X86DAGToDAGISel::EmitSpecialCodeForMain(MachineBasicBlock *BB, + MachineFrameInfo *MFI) { + const TargetInstrInfo *TII = TM.getInstrInfo(); + if (Subtarget->isTargetCygMing()) + BuildMI(BB, TII->get(X86::CALLpcrel32)).addExternalSymbol("__main"); +} + +void X86DAGToDAGISel::EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) { + // If this is main, emit special code for main. + MachineBasicBlock *BB = MF.begin(); + if (Fn.hasExternalLinkage() && Fn.getName() == "main") + EmitSpecialCodeForMain(BB, MF.getFrameInfo()); +} + /// MatchAddress - Add the specified node to the specified addressing mode, /// returning true if it cannot be done. This just pattern matches for the /// addressing mode From fjahanian at apple.com Tue Sep 25 14:44:06 2007 From: fjahanian at apple.com (Fariborz Jahanian) Date: Tue, 25 Sep 2007 14:44:06 -0700 Subject: [llvm-commits] [llvm-gcc-4.0] r42287 - in /llvm-gcc-4.0/trunk/gcc: c-common.h llvm-backend.cpp objc/objc-act.c stub-objc.c In-Reply-To: References: <200709250251.l8P2pI2f010914@zion.cs.uiuc.edu> Message-ID: <8E97846B-4B01-450E-9EDA-04DA08A4573E@apple.com> On Sep 25, 2007, at 2:29 PM, Chris Lattner wrote: > On Sep 24, 2007, at 7:51 PM, Bill Wendling wrote: >> URL: http://llvm.org/viewvc/llvm-project?rev=42287&view=rev >> Log: >> During the processing of Objective-C "protocols", the objc frontend >> creates two >> decls for the protocol. One for the metadata and another for when >> it's >> referenced. However, protocols are "internal global", so when we do >> a lookup >> for the reference, it doesn't find the first decl because it's not >> "external". >> This will perform a second lookup for objective C protocols if we >> don't find >> it among the "external globals". > > Hi Bill, > > This is a good short-term solution Bill, but I don't think it is > what we want to keep. > > Specifically, your new function adds a fairly expensive call to > strstr to the global variable emission path for all languages. > > It would be better to merge the vardecls in objc-act.c where it > creates them. I see this code: > > /* Build decl = initializer; for each protocol referenced in > @protocol(MyProtole) expression. */ > > static void > build_protocollist_translation_table (void) > { > tree chain; > static char string[BUFSIZE]; > > for (chain = protocollist_ref_chain; chain; chain = TREE_CHAIN > (chain)) > { > tree expr = TREE_VALUE (chain); > tree decl = TREE_PURPOSE (chain); > gcc_assert (TREE_CODE (expr) == PROTOCOL_INTERFACE_TYPE); > /* APPLE LOCAL begin radar 4695109 */ > sprintf (string, "_OBJC_PROTOCOL_$_%s", > IDENTIFIER_POINTER (PROTOCOL_NAME (expr))); > expr = start_var_decl (objc_v2_protocol_template, string); > /* APPLE LOCAL end radar 4695109 */ > expr = convert (objc_protocol_type, build_fold_addr_expr (expr)); > finish_var_decl (decl, expr); > } > } > > and this: > > static void > build_v2_protocol_reference (tree p) > { > tree decl; > const char *proto_name; > > /* static struct protocol_t _OBJC_PROTOCOL_$; */ > > proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_$", p); > decl = start_var_decl (objc_v2_protocol_template, proto_name); > PROTOCOL_V2_FORWARD_DECL (p) = decl; > } > > I'm not sure which happens first, but this is creating two DECL > nodes with the same name. Can you please investigate using > lookup_name to only build_v2_protocol_reference happens first, which is caused by @protocol expression in user code. The other one is related to meta- data generaiton which comes at the very end. - fariborz > create the new var_decl node if it doesn't already exist? > > It might just be a matter of changing the code to looks like this: > > proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_$", p); > if ((decl = lookup_name(proto_name)) == 0) > decl = start_var_decl (objc_v2_protocol_template, proto_name); > PROTOCOL_V2_FORWARD_DECL (p) = decl; > > Or something. > > -Chris > > > >> Modified: >> llvm-gcc-4.0/trunk/gcc/c-common.h >> llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp >> llvm-gcc-4.0/trunk/gcc/objc/objc-act.c >> llvm-gcc-4.0/trunk/gcc/stub-objc.c >> >> Modified: llvm-gcc-4.0/trunk/gcc/c-common.h >> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/c-common.h?rev=42287&r1=42286&r2=42287&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm-gcc-4.0/trunk/gcc/c-common.h (original) >> +++ llvm-gcc-4.0/trunk/gcc/c-common.h Mon Sep 24 21:51:18 2007 >> @@ -1139,6 +1139,12 @@ >> extern void objc_remove_weak_read (tree*); >> /* APPLE LOCAL end radar 4426814 */ >> >> +/* APPLE LOCAL begin - LLVM radar 5476262 */ >> +#ifdef ENABLE_LLVM >> +extern bool objc_is_protocol_reference (const char *name); >> +#endif >> +/* APPLE LOCAL end - LLVM radar 5476262 */ >> + >> /* APPLE LOCAL begin C* language */ >> extern void objc_set_method_opt (int); >> void objc_finish_foreach_loop (location_t, tree, tree, tree, tree); >> >> Modified: llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp?rev=42287&r1=42286&r2=42287&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp (original) >> +++ llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Mon Sep 24 21:51:18 2007 >> @@ -66,6 +66,7 @@ >> #include "function.h" >> #include "tree-inline.h" >> #include "langhooks.h" >> +#include "c-common.h" >> } >> >> // Non-zero if bytecode from PCH is successfully read. >> @@ -1060,6 +1061,14 @@ >> // If the global has a name, prevent multiple vars with the >> same name from >> // being created. >> GlobalVariable *GVE = TheModule->getGlobalVariable(Name); >> + >> + // And Objective-C "@protocol" will create a decl for the >> + // protocol metadata and then when the protocol is >> + // referenced. However, protocols have file-scope, so they >> + // aren't found in the GlobalVariable list unless we look at >> + // non-extern globals as well. >> + if (!GVE && c_dialect_objc() && >> objc_is_protocol_reference(Name)) >> + GVE = TheModule->getGlobalVariable(Name, true); >> >> if (GVE == 0) { >> GV = new GlobalVariable(Ty, false, >> GlobalValue::ExternalLinkage,0, >> >> 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=42287&r1=42286&r2=42287&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm-gcc-4.0/trunk/gcc/objc/objc-act.c (original) >> +++ llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Mon Sep 24 21:51:18 2007 >> @@ -11669,6 +11669,19 @@ >> } >> } >> >> +/* APPLE LOCAL begin - LLVM radar 5476262 */ >> +#ifdef ENABLE_LLVM >> +/* This routine returns true if the name is the same as a protocol >> + reference name. */ >> + >> +bool >> +objc_is_protocol_reference (const char *name) >> +{ >> + return flag_objc_abi == 2 && strstr (name, "_OBJC_PROTOCOL_$_") ! >> = 0; >> +} >> +#endif >> +/* APPLE LOCAL end - LLVM radar 5476262 */ >> + >> /* This routine builds the protocol_reference_chain for each >> protocol name used >> @protocol(MyProtocol) expression. IDENT is current protocol >> name. */ >> >> >> Modified: llvm-gcc-4.0/trunk/gcc/stub-objc.c >> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/stub-objc.c?rev=42287&r1=42286&r2=42287&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm-gcc-4.0/trunk/gcc/stub-objc.c (original) >> +++ llvm-gcc-4.0/trunk/gcc/stub-objc.c Mon Sep 24 21:51:18 2007 >> @@ -548,3 +548,13 @@ >> return false; >> } >> /* APPLE LOCAL end radar 4985544 */ >> + >> +/* APPLE LOCAL begin - LLVM radar 5476262 */ >> +#ifdef ENABLE_LLVM >> +bool >> +objc_is_protocol_reference (const char * ARG_UNUSED(name)) >> +{ >> + return false; >> +} >> +#endif >> +/* APPLE LOCAL end - LLVM radar 5476262 */ >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From clattner at apple.com Tue Sep 25 15:00:23 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 25 Sep 2007 15:00:23 -0700 Subject: [llvm-commits] [llvm-gcc-4.0] r42287 - in /llvm-gcc-4.0/trunk/gcc: c-common.h llvm-backend.cpp objc/objc-act.c stub-objc.c In-Reply-To: <16e5fdf90709251438t564b51d4n62e06483c5deb9c8@mail.gmail.com> References: <200709250251.l8P2pI2f010914@zion.cs.uiuc.edu> <16e5fdf90709251438t564b51d4n62e06483c5deb9c8@mail.gmail.com> Message-ID: <00278F87-5CF8-498D-AB06-33CB3EAA00E9@apple.com> On Sep 25, 2007, at 2:38 PM, Bill Wendling wrote: >> It might just be a matter of changing the code to looks like this: >> >> proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_$", p); >> if ((decl = lookup_name(proto_name)) == 0) >> decl = start_var_decl (objc_v2_protocol_template, proto_name); >> PROTOCOL_V2_FORWARD_DECL (p) = decl; >> >> Or something. >> > You read my mind! :-) I'm testing something akin to this right now, > actually. I'll let you know how it goes. > Great, thanks Bill! -Chris From evan.cheng at apple.com Tue Sep 25 15:10:43 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 Sep 2007 22:10:43 -0000 Subject: [llvm-commits] [llvm] r42323 - /llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <200709252210.l8PMAhFc030174@zion.cs.uiuc.edu> Author: evancheng Date: Tue Sep 25 17:10:43 2007 New Revision: 42323 URL: http://llvm.org/viewvc/llvm-project?rev=42323&view=rev Log: Missing load / store folding entries. 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=42323&r1=42322&r2=42323&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Tue Sep 25 17:10:43 2007 @@ -700,6 +700,10 @@ { X86::NEW_SETNSr, X86::NEW_SETNSm }, { X86::NEW_SETPr, X86::NEW_SETPm }, { X86::NEW_SETSr, X86::NEW_SETSm }, + { X86::NEW_TEST16ri,X86::NEW_TEST16mi }, + { X86::NEW_TEST32ri,X86::NEW_TEST32mi }, + { X86::NEW_TEST64ri32, X86::NEW_TEST64mi32 }, + { X86::NEW_TEST8ri, X86::NEW_TEST8mi }, { X86::SETAEr, X86::SETAEm }, { X86::SETAr, X86::SETAm }, @@ -813,6 +817,10 @@ { X86::MOVZX64rr8, X86::MOVZX64rm8 }, // TEMPORARY + { X86::NEW_CMP16rr, X86::NEW_CMP16rm }, + { X86::NEW_CMP32rr, X86::NEW_CMP32rm }, + { X86::NEW_CMP64rr, X86::NEW_CMP64rm }, + { X86::NEW_CMP8rr, X86::NEW_CMP8rm }, { X86::NEW_Int_COMISDrr, X86::NEW_Int_COMISDrm }, { X86::NEW_Int_COMISSrr, X86::NEW_Int_COMISSrm }, { X86::NEW_Int_UCOMISDrr, X86::NEW_Int_UCOMISDrm }, From sabre at nondot.org Tue Sep 25 15:37:51 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 25 Sep 2007 22:37:51 -0000 Subject: [llvm-commits] [llvm] r42324 - /llvm/trunk/docs/ProgrammersManual.html Message-ID: <200709252237.l8PMbqel031277@zion.cs.uiuc.edu> Author: lattner Date: Tue Sep 25 17:37:50 2007 New Revision: 42324 URL: http://llvm.org/viewvc/llvm-project?rev=42324&view=rev Log: explain why not vector Modified: llvm/trunk/docs/ProgrammersManual.html Modified: llvm/trunk/docs/ProgrammersManual.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ProgrammersManual.html?rev=42324&r1=42323&r2=42324&view=diff ============================================================================== --- llvm/trunk/docs/ProgrammersManual.html (original) +++ llvm/trunk/docs/ProgrammersManual.html Tue Sep 25 17:37:50 2007 @@ -1292,8 +1292,15 @@
    -Unlike the other containers, there are only two bit storage containers, and when -to use each is relatively straightforward. +

    Unlike the other containers, there are only two bit storage containers, and +choosing when to use each is relatively straightforward.

    + +

    One additional option is +std::vector<bool>: we discourage its use for two reasons 1) the +implementation in many common compilers (e.g. commonly available versions of +GCC) is extremely inefficient and 2) the C++ standards committee is likely to +deprecate this container and/or change it significantly somehow. In any case, +please don't use it.

    From dpatel at apple.com Tue Sep 25 15:42:51 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 25 Sep 2007 22:42:51 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r42325 - /llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Message-ID: <200709252242.l8PMgpB1031413@zion.cs.uiuc.edu> Author: dpatel Date: Tue Sep 25 17:42:51 2007 New Revision: 42325 URL: http://llvm.org/viewvc/llvm-project?rev=42325&view=rev Log: Do not hide objc_class_name_Foo even if -fvisibility=hidden is set. 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=42325&r1=42324&r2=42325&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Tue Sep 25 17:42:51 2007 @@ -17961,6 +17961,8 @@ DECL_ARTIFICIAL (decl) = 1; /* LLVM LOCAL begin */ #ifdef ENABLE_LLVM + DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; + DECL_VISIBILITY_SPECIFIED (decl) = 1; set_user_assembler_name(decl, string); /* Let optimizer know that this decl is not removable. */ DECL_PRESERVE_P (decl) = 1; From dpatel at apple.com Tue Sep 25 15:44:35 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 25 Sep 2007 22:44:35 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42326 - /llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Message-ID: <200709252244.l8PMiaNY031496@zion.cs.uiuc.edu> Author: dpatel Date: Tue Sep 25 17:44:35 2007 New Revision: 42326 URL: http://llvm.org/viewvc/llvm-project?rev=42326&view=rev Log: Do not hide objc_class_name_Foo even if -fvisibility=hidden is set. 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=42326&r1=42325&r2=42326&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Tue Sep 25 17:44:35 2007 @@ -18249,6 +18249,8 @@ DECL_ARTIFICIAL (decl) = 1; /* APPLE LOCAL begin LLVM */ #ifdef ENABLE_LLVM + DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; + DECL_VISIBILITY_SPECIFIED (decl) = 1; set_user_assembler_name(decl, string); /* Let optimizer know that this decl is not removable. */ DECL_PRESERVE_P (decl) = 1; From gabor at mac.com Tue Sep 25 15:50:29 2007 From: gabor at mac.com (Gabor Greif) Date: Wed, 26 Sep 2007 00:50:29 +0200 Subject: [llvm-commits] [llvm] r42324 - /llvm/trunk/docs/ProgrammersManual.html Message-ID: <70545E3B-4868-4C0D-9997-EEBB01880E21@mac.com> What about doing something like this: #ifdef DEBUG template <> struct std::default_alloc< std::vector< bool > > {}; #endif It should (modulo my typos) make allocation of all vector impossible in the debug builds. Just an idea. Cheers, Gabor From neil at daikokuya.co.uk Tue Sep 25 15:31:08 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Wed, 26 Sep 2007 07:31:08 +0900 Subject: [llvm-commits] [llvm] r42303 - in /llvm/trunk/test/CodeGen/X86: ldzero.ll nancvt.ll In-Reply-To: <200709251750.l8PHotYr020560@zion.cs.uiuc.edu> References: <200709251750.l8PHotYr020560@zion.cs.uiuc.edu> Message-ID: <20070925223108.GJ19035@daikokuya.co.uk> Dale Johannesen wrote:- > Author: johannes > Date: Tue Sep 25 12:50:55 2007 > New Revision: 42303 > > URL: http://llvm.org/viewvc/llvm-project?rev=42303&view=rev > Log: > Some tests for APFloat conversions. Sorry if it's a dumb question; how do I run these tests? Neil. From dalej at apple.com Tue Sep 25 16:04:34 2007 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 Sep 2007 16:04:34 -0700 Subject: [llvm-commits] [llvm] r42303 - in /llvm/trunk/test/CodeGen/X86: ldzero.ll nancvt.ll In-Reply-To: <20070925223108.GJ19035@daikokuya.co.uk> References: <200709251750.l8PHotYr020560@zion.cs.uiuc.edu> <20070925223108.GJ19035@daikokuya.co.uk> Message-ID: <23705CDE-EC63-4E60-BD07-F96BEE913F4E@apple.com> On Sep 25, 2007, at 3:31 PM, Neil Booth wrote: > Dale Johannesen wrote:- > >> Author: johannes >> Date: Tue Sep 25 12:50:55 2007 >> New Revision: 42303 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=42303&view=rev >> Log: >> Some tests for APFloat conversions. > > Sorry if it's a dumb question; how do I run these tests? > > Neil. cd llvm/test make You might have to configure the first time, although I think the top level configure does it. Uses dejagnu. I don't know a way to run individual tests, but the suite takes about 5 minutes. From dalej at apple.com Tue Sep 25 16:07:07 2007 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 Sep 2007 23:07:07 -0000 Subject: [llvm-commits] [llvm] r42328 - in /llvm/trunk/lib: Support/APFloat.cpp VMCore/ConstantFold.cpp Message-ID: <200709252307.l8PN7855032202@zion.cs.uiuc.edu> Author: johannes Date: Tue Sep 25 18:07:07 2007 New Revision: 42328 URL: http://llvm.org/viewvc/llvm-project?rev=42328&view=rev Log: Make APFloat->int conversions deterministic even in cases with undefined behavior. Modified: llvm/trunk/lib/Support/APFloat.cpp llvm/trunk/lib/VMCore/ConstantFold.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=42328&r1=42327&r2=42328&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Tue Sep 25 18:07:07 2007 @@ -1399,13 +1399,28 @@ unsigned int msb, partsCount; int bits; - /* Handle the three special cases first. */ - if(category == fcInfinity || category == fcNaN) - return opInvalidOp; - partsCount = partCountForBits(width); - if(category == fcZero) { + /* Handle the three special cases first. We produce + a deterministic result even for the Invalid cases. */ + if (category == fcNaN) { + // Neither sign nor isSigned affects this. + APInt::tcSet(parts, 0, partsCount); + return opInvalidOp; + } + if (category == fcInfinity) { + if (!sign && isSigned) + APInt::tcSetLeastSignificantBits(parts, partsCount, width-1); + else if (!sign && !isSigned) + APInt::tcSetLeastSignificantBits(parts, partsCount, width); + else if (sign && isSigned) { + APInt::tcSetLeastSignificantBits(parts, partsCount, 1); + APInt::tcShiftLeft(parts, partsCount, width-1); + } else // sign && !isSigned + APInt::tcSet(parts, 0, partsCount); + return opInvalidOp; + } + if (category == fcZero) { APInt::tcSet(parts, 0, partsCount); return opOK; } @@ -1418,6 +1433,19 @@ if(bits > 0) { lost_fraction = tmp.shiftSignificandRight(bits); } else { + if (-bits >= semantics->precision) { + // Unrepresentably large. + if (!sign && isSigned) + APInt::tcSetLeastSignificantBits(parts, partsCount, width-1); + else if (!sign && !isSigned) + APInt::tcSetLeastSignificantBits(parts, partsCount, width); + else if (sign && isSigned) { + APInt::tcSetLeastSignificantBits(parts, partsCount, 1); + APInt::tcShiftLeft(parts, partsCount, width-1); + } else // sign && !isSigned + APInt::tcSet(parts, 0, partsCount); + return (opStatus)(opOverflow | opInexact); + } tmp.shiftSignificandLeft(-bits); lost_fraction = lfExactlyZero; } Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=42328&r1=42327&r2=42328&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ConstantFold.cpp (original) +++ llvm/trunk/lib/VMCore/ConstantFold.cpp Tue Sep 25 18:07:07 2007 @@ -197,8 +197,6 @@ APFloat::opStatus status = V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI, APFloat::rmTowardZero); - if (status!=APFloat::opOK && status!=APFloat::opInexact) - return 0; // give up APInt Val(DestBitWidth, 2, x); return ConstantInt::get(Val); } From lattner at apple.com Tue Sep 25 16:13:17 2007 From: lattner at apple.com (Tanya Lattner) Date: Tue, 25 Sep 2007 16:13:17 -0700 Subject: [llvm-commits] [llvm] r42303 - in /llvm/trunk/test/CodeGen/X86: ldzero.ll nancvt.ll In-Reply-To: <23705CDE-EC63-4E60-BD07-F96BEE913F4E@apple.com> References: <200709251750.l8PHotYr020560@zion.cs.uiuc.edu> <20070925223108.GJ19035@daikokuya.co.uk> <23705CDE-EC63-4E60-BD07-F96BEE913F4E@apple.com> Message-ID: <3BA62453-5CB0-447B-A9FF-7A90A7AF2BC2@apple.com> On Sep 25, 2007, at 4:04 PM, Dale Johannesen wrote: > > On Sep 25, 2007, at 3:31 PM, Neil Booth wrote: > >> Dale Johannesen wrote:- >> >>> Author: johannes >>> Date: Tue Sep 25 12:50:55 2007 >>> New Revision: 42303 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=42303&view=rev >>> Log: >>> Some tests for APFloat conversions. >> >> Sorry if it's a dumb question; how do I run these tests? >> >> Neil. > > cd llvm/test > make > > You might have to configure the first time, although I think the top > level configure does it. > Uses dejagnu. I don't know a way to run individual tests, but the > suite takes about 5 minutes. > make TESTSUITE=CodeGen/X86 That will run the subdir. To run individual test: ./TestRunner.sh CodeGen/X86/ldzero.ll -Tanya > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Tue Sep 25 16:32:20 2007 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 Sep 2007 23:32:20 -0000 Subject: [llvm-commits] [llvm] r42329 - /llvm/trunk/lib/VMCore/ConstantFold.cpp Message-ID: <200709252332.l8PNWKWv001092@zion.cs.uiuc.edu> Author: johannes Date: Tue Sep 25 18:32:20 2007 New Revision: 42329 URL: http://llvm.org/viewvc/llvm-project?rev=42329&view=rev Log: Remove no-longer-used variable. Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=42329&r1=42328&r2=42329&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ConstantFold.cpp (original) +++ llvm/trunk/lib/VMCore/ConstantFold.cpp Tue Sep 25 18:32:20 2007 @@ -194,9 +194,8 @@ APFloat V = FPC->getValueAPF(); uint64_t x[2]; uint32_t DestBitWidth = cast(DestTy)->getBitWidth(); - APFloat::opStatus status = V.convertToInteger(x, DestBitWidth, - opc==Instruction::FPToSI, - APFloat::rmTowardZero); + (void) V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI, + APFloat::rmTowardZero); APInt Val(DestBitWidth, 2, x); return ConstantInt::get(Val); } From dberlin at dberlin.org Tue Sep 25 17:11:59 2007 From: dberlin at dberlin.org (Daniel Berlin) Date: Wed, 26 Sep 2007 00:11:59 -0000 Subject: [llvm-commits] [llvm] r42331 - /llvm/trunk/include/llvm/ADT/SparseBitVector.h Message-ID: <200709260011.l8Q0BxHg002805@zion.cs.uiuc.edu> Author: dannyb Date: Tue Sep 25 19:11:59 2007 New Revision: 42331 URL: http://llvm.org/viewvc/llvm-project?rev=42331&view=rev Log: Fix small bug in operator== for iterators Modified: llvm/trunk/include/llvm/ADT/SparseBitVector.h Modified: llvm/trunk/include/llvm/ADT/SparseBitVector.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SparseBitVector.h?rev=42331&r1=42330&r2=42331&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/SparseBitVector.h (original) +++ llvm/trunk/include/llvm/ADT/SparseBitVector.h Tue Sep 25 19:11:59 2007 @@ -441,7 +441,7 @@ bool operator==(const SparseBitVectorIterator &RHS) const { // If they are both at the end, ignore the rest of the fields. - if (AtEnd == RHS.AtEnd) + if (AtEnd && RHS.AtEnd) return true; // Otherwise they are the same if they have the same bit number and // bitmap. From asl at math.spbu.ru Tue Sep 25 17:13:34 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Wed, 26 Sep 2007 00:13:34 -0000 Subject: [llvm-commits] [llvm] r42332 - /llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <200709260013.l8Q0DYOB002896@zion.cs.uiuc.edu> Author: asl Date: Tue Sep 25 19:13:34 2007 New Revision: 42332 URL: http://llvm.org/viewvc/llvm-project?rev=42332&view=rev Log: Correctly restore stack pointer after realignment in main() on Cygwin/Mingw32 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=42332&r1=42331&r2=42332&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Tue Sep 25 19:13:34 2007 @@ -1545,7 +1545,9 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); + const Function* Fn = MF.getFunction(); X86MachineFunctionInfo *X86FI = MF.getInfo(); + const X86Subtarget* Subtarget = &MF.getTarget().getSubtarget(); MachineBasicBlock::iterator MBBI = prior(MBB.end()); unsigned RetOpcode = MBBI->getOpcode(); @@ -1602,7 +1604,12 @@ // If dynamic alloca is used, then reset esp to point to the last // callee-saved slot before popping them off! - if (MFI->hasVarSizedObjects()) { + // Also, if it's main() on Cygwin/Mingw32 we aligned stack in the prologue, - revert + // stack changes back. Note: we're assuming, that frame pointer was forced + // for main() + if (MFI->hasVarSizedObjects() || + (Fn->hasExternalLinkage() && Fn->getName() == "main" && + Subtarget->isTargetCygMing())) { unsigned Opc = Is64Bit ? X86::LEA64r : X86::LEA32r; if (CSSize) { MachineInstr *MI = addRegOffset(BuildMI(TII.get(Opc), StackPtr), From evan.cheng at apple.com Tue Sep 25 17:45:55 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Sep 2007 00:45:55 -0000 Subject: [llvm-commits] [llvm] r42333 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200709260045.l8Q0jtri004551@zion.cs.uiuc.edu> Author: evancheng Date: Tue Sep 25 19:45:55 2007 New Revision: 42333 URL: http://llvm.org/viewvc/llvm-project?rev=42333&view=rev Log: translateX86CC updates the last two operands. 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=42333&r1=42332&r2=42333&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Sep 25 19:45:55 2007 @@ -3719,6 +3719,7 @@ SDOperand X86TargetLowering::LowerSETCC_New(SDOperand Op, SelectionDAG &DAG) { assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer"); + SDOperand Cond; SDOperand Op0 = Op.getOperand(0); SDOperand Op1 = Op.getOperand(1); SDOperand CC = Op.getOperand(2); @@ -3726,14 +3727,16 @@ bool isFP = MVT::isFloatingPoint(Op.getOperand(1).getValueType()); unsigned X86CC; - SDOperand Cond = DAG.getNode(X86ISD::CMP_NEW, MVT::i32, Op0, Op1); if (translateX86CC(cast(CC)->get(), isFP, X86CC, - Op0, Op1, DAG)) + Op0, Op1, DAG)) { + Cond = DAG.getNode(X86ISD::CMP_NEW, MVT::i32, Op0, Op1); return DAG.getNode(X86ISD::SETCC_NEW, MVT::i8, DAG.getConstant(X86CC, MVT::i8), Cond); + } assert(isFP && "Illegal integer SetCC!"); + Cond = DAG.getNode(X86ISD::CMP_NEW, MVT::i32, Op0, Op1); switch (SetCCOpcode) { default: assert(false && "Illegal floating point SetCC!"); case ISD::SETOEQ: { // !PF & ZF From evan.cheng at apple.com Tue Sep 25 18:29:07 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Sep 2007 01:29:07 -0000 Subject: [llvm-commits] [llvm] r42335 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.td X86InstrX86-64.td Message-ID: <200709260129.l8Q1T7wV006546@zion.cs.uiuc.edu> Author: evancheng Date: Tue Sep 25 20:29:06 2007 New Revision: 42335 URL: http://llvm.org/viewvc/llvm-project?rev=42335&view=rev Log: Add pushf{d|q}, popf{d|q} to push and pop EFLAGS register. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td llvm/trunk/lib/Target/X86/X86InstrX86-64.td Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=42335&r1=42334&r2=42335&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Tue Sep 25 20:29:06 2007 @@ -424,13 +424,16 @@ (outs), (ins), "leave", []>; let Defs = [ESP], Uses = [ESP] in { -def POP32r : I<0x58, AddRegFrm, - (outs GR32:$reg), (ins), "pop{l}\t$reg", []>; +def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>; -def PUSH32r : I<0x50, AddRegFrm, - (outs), (ins GR32:$reg), "push{l}\t$reg", []>; +def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>; } +let Defs = [ESP, EFLAGS], Uses = [ESP] in +def POPD : I<0x9D, RawFrm, (outs), (ins), "popfd", []>; +let Defs = [ESP], Uses = [ESP, EFLAGS] in +def PUSHFD : I<0x9C, RawFrm, (outs), (ins), "pushfd", []>; + def MovePCtoStack : I<0, Pseudo, (outs), (ins piclabel:$label), "call\t$label", []>; 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=42335&r1=42334&r2=42335&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrX86-64.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrX86-64.td Tue Sep 25 20:29:06 2007 @@ -123,6 +123,11 @@ (outs), (ins GR64:$reg), "push{q}\t$reg", []>; } +let Defs = [RSP, EFLAGS], Uses = [RSP] in +def POPQ : I<0x9D, RawFrm, (outs), (ins), "popfq", []>, REX_W; +let Defs = [RSP], Uses = [RSP, EFLAGS] in +def PUSHFQ : I<0x9C, RawFrm, (outs), (ins), "pushfq", []>; + def LEA64_32r : I<0x8D, MRMSrcMem, (outs GR32:$dst), (ins lea64_32mem:$src), "lea{l}\t{$src|$dst}, {$dst|$src}", From baldrick at free.fr Tue Sep 25 20:22:28 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 Sep 2007 03:22:28 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42336 - /llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Message-ID: <200709260322.l8Q3MSpJ010741@zion.cs.uiuc.edu> Author: baldrick Date: Tue Sep 25 22:22:27 2007 New Revision: 42336 URL: http://llvm.org/viewvc/llvm-project?rev=42336&view=rev Log: Handle scalar to aggregate VIEW_CONVERT_EXPR lvalue. Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.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=42336&r1=42335&r2=42336&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Tue Sep 25 22:22:27 2007 @@ -5517,12 +5517,22 @@ } LValue TreeToLLVM::EmitLV_VIEW_CONVERT_EXPR(tree exp) { - // The address is the address of the operand. - LValue LV = EmitLV(TREE_OPERAND(exp, 0)); - // The type is the type of the expression. - const Type *Ty = ConvertType(TREE_TYPE(exp)); - LV.Ptr = BitCastToType(LV.Ptr, PointerType::get(Ty)); - return LV; + tree Op = TREE_OPERAND(exp, 0); + + if (isAggregateTreeType(TREE_TYPE(Op))) { + // If the input is an aggregate, the address is the address of the operand. + LValue LV = EmitLV(Op); + // The type is the type of the expression. + LV.Ptr = BitCastToType(LV.Ptr, PointerType::get(ConvertType(TREE_TYPE(exp)))); + return LV; + } else { + // If the input is a scalar, emit to a temporary. + Value *Dest = CreateTemporary(ConvertType(TREE_TYPE(Op))); + Builder.CreateStore(Emit(Op, 0), Dest); + // The type is the type of the expression. + Dest = BitCastToType(Dest, PointerType::get(ConvertType(TREE_TYPE(exp)))); + return LValue(Dest); + } } //===----------------------------------------------------------------------===// From baldrick at free.fr Tue Sep 25 20:23:50 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 Sep 2007 05:23:50 +0200 Subject: [llvm-commits] [llvm-gcc-4.2] r42315 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: References: <200709252012.l8PKCEfk026168@zion.cs.uiuc.edu> Message-ID: <200709260523.51260.baldrick@free.fr> > This should also be safe to apply to 4.0, right? I was testing it compiles :) Now applied. Ciao, Duncan. From baldrick at free.fr Tue Sep 25 20:35:55 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 Sep 2007 03:35:55 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r42337 - /llvm-gcc-4.2/trunk/gcc/config/i386/i386.h Message-ID: <200709260335.l8Q3ZtJ1011114@zion.cs.uiuc.edu> Author: baldrick Date: Tue Sep 25 22:35:54 2007 New Revision: 42337 URL: http://llvm.org/viewvc/llvm-project?rev=42337&view=rev Log: Restore wrongly deleted line. Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.h Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/i386.h?rev=42337&r1=42336&r2=42337&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/i386.h (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/i386.h Tue Sep 25 22:35:54 2007 @@ -565,6 +565,8 @@ /* target machine storage layout */ +#define LONG_DOUBLE_TYPE_SIZE 80 + /* Set the value of FLT_EVAL_METHOD in float.h. When using only the FPU, assume that the fpcw is set to extended precision; when using only SSE, rounding is correct; when using both SSE and the FPU, From clattner at apple.com Tue Sep 25 20:48:45 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 25 Sep 2007 20:48:45 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r42315 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <200709260523.51260.baldrick@free.fr> References: <200709252012.l8PKCEfk026168@zion.cs.uiuc.edu> <200709260523.51260.baldrick@free.fr> Message-ID: <61F56C05-5B2A-4487-AC17-CF7C8195009E@apple.com> On Sep 25, 2007, at 8:23 PM, Duncan Sands wrote: >> This should also be safe to apply to 4.0, right? > > I was testing it compiles :) Now applied. Nice, thanks Duncan! -Chris From baldrick at free.fr Tue Sep 25 21:04:30 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 Sep 2007 04:04:30 -0000 Subject: [llvm-commits] [llvm] r42338 - /llvm/trunk/test/CFrontend/2007-09-26-Alignment.c Message-ID: <200709260404.l8Q44UIi011764@zion.cs.uiuc.edu> Author: baldrick Date: Tue Sep 25 23:04:29 2007 New Revision: 42338 URL: http://llvm.org/viewvc/llvm-project?rev=42338&view=rev Log: Test that local variables are aligned as the user requested. Added: llvm/trunk/test/CFrontend/2007-09-26-Alignment.c Added: llvm/trunk/test/CFrontend/2007-09-26-Alignment.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/2007-09-26-Alignment.c?rev=42338&view=auto ============================================================================== --- llvm/trunk/test/CFrontend/2007-09-26-Alignment.c (added) +++ llvm/trunk/test/CFrontend/2007-09-26-Alignment.c Tue Sep 25 23:04:29 2007 @@ -0,0 +1,7 @@ +// RUN: %llvmgcc -S %s -o - | grep {align 16} +extern p(int *); +int q(void) { + int x __attribute__ ((aligned (16))); + p(&x); + return x; +} From baldrick at free.fr Tue Sep 25 21:14:46 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 Sep 2007 04:14:46 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42339 - /llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Message-ID: <200709260414.l8Q4EkqQ012091@zion.cs.uiuc.edu> Author: baldrick Date: Tue Sep 25 23:14:45 2007 New Revision: 42339 URL: http://llvm.org/viewvc/llvm-project?rev=42339&view=rev Log: Get rid of the old code for aligning locals, which did funky stuff like DECL_ALIGN(decl) = GET_MODE_BITSIZE(DECL_MODE(decl)); (copied from RTL), and instead just set the alignment according to DECL_ALIGN using the same logic as for global variables. This fixes two problems: (1) user requested alignment was being ignored; and (2) the compiler wouldn't build on x86 due to long doubles being given an alignment of 12 (not a power of 2). Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.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=42339&r1=42338&r2=42339&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Tue Sep 25 23:14:45 2007 @@ -1539,11 +1539,10 @@ // eliminated all uses of, but is preserving for debug info, ignore it. if (TREE_CODE(decl) == VAR_DECL && DECL_VALUE_EXPR(decl)) return; - - const Type *Ty; // Type to allocate - Value *Size = 0; // Amount to alloca (null for 1) - unsigned Alignment = 0; // Alignment in bytes. - + + const Type *Ty; // Type to allocate + Value *Size = 0; // Amount to alloca (null for 1) + if (DECL_SIZE(decl) == 0) { // Variable with incomplete type. if (DECL_INITIAL(decl) == 0) return; // Error message was already done; now avoid a crash. @@ -1555,14 +1554,6 @@ } else if (TREE_CODE(DECL_SIZE_UNIT(decl)) == INTEGER_CST) { // Variable of fixed size that goes on the stack. Ty = ConvertType(type); - - // Set alignment we actually gave this decl. - if (DECL_MODE(decl) == BLKmode) - DECL_ALIGN(decl) = BIGGEST_ALIGNMENT; - else - DECL_ALIGN(decl) = GET_MODE_BITSIZE(DECL_MODE(decl)); - DECL_USER_ALIGN(decl) = 0; - Alignment = DECL_ALIGN(decl)/8; } else { tree length; @@ -1580,7 +1571,18 @@ } Size = CastToUIntType(Size, Type::Int32Ty); } - + + unsigned Alignment = 0; // Alignment in bytes. + + // Set the alignment for the local if one of the following condition is met + // 1) DECL_ALIGN_UNIT does not match alignment as per ABI specification + // 2) DECL_ALIGN is set by user. + if (DECL_ALIGN_UNIT(decl)) { + unsigned TargetAlign = getTargetData().getABITypeAlignment(Ty); + if (DECL_USER_ALIGN(decl) || TargetAlign != (unsigned)DECL_ALIGN_UNIT(decl)) + Alignment = DECL_ALIGN_UNIT(decl); + } + const char *Name; // Name of variable if (DECL_NAME(decl)) Name = IDENTIFIER_POINTER(DECL_NAME(decl)); From baldrick at free.fr Tue Sep 25 21:17:07 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 Sep 2007 04:17:07 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r42340 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200709260417.l8Q4H7P6012147@zion.cs.uiuc.edu> Author: baldrick Date: Tue Sep 25 23:17:07 2007 New Revision: 42340 URL: http://llvm.org/viewvc/llvm-project?rev=42340&view=rev Log: Get rid of the old code for aligning locals, which did funky stuff like DECL_ALIGN(decl) = GET_MODE_BITSIZE(DECL_MODE(decl)); (copied from RTL), and instead just set the alignment according to DECL_ALIGN using the same logic as for global variables. This fixes two problems: (1) user requested alignment was being ignored; and (2) the compiler wouldn't build on x86 due to long doubles being given an alignment of 12 (not a power of 2). Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=42340&r1=42339&r2=42340&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Sep 25 23:17:07 2007 @@ -1485,11 +1485,10 @@ // eliminated all uses of, but is preserving for debug info, ignore it. if (TREE_CODE(decl) == VAR_DECL && DECL_VALUE_EXPR(decl)) return; - - const Type *Ty; // Type to allocate - Value *Size = 0; // Amount to alloca (null for 1) - unsigned Alignment = 0; // Alignment in bytes. - + + const Type *Ty; // Type to allocate + Value *Size = 0; // Amount to alloca (null for 1) + if (DECL_SIZE(decl) == 0) { // Variable with incomplete type. if (DECL_INITIAL(decl) == 0) return; // Error message was already done; now avoid a crash. @@ -1501,14 +1500,6 @@ } else if (TREE_CODE(DECL_SIZE_UNIT(decl)) == INTEGER_CST) { // Variable of fixed size that goes on the stack. Ty = ConvertType(type); - - // Set alignment we actually gave this decl. - if (DECL_MODE(decl) == BLKmode) - DECL_ALIGN(decl) = BIGGEST_ALIGNMENT; - else - DECL_ALIGN(decl) = GET_MODE_BITSIZE(DECL_MODE(decl)); - DECL_USER_ALIGN(decl) = 0; - Alignment = DECL_ALIGN(decl)/8; } else { // Dynamic-size object: must push space on the stack. if (TREE_CODE(type) == ARRAY_TYPE @@ -1528,7 +1519,18 @@ } Size = CastToUIntType(Size, Type::Int32Ty); } - + + unsigned Alignment = 0; // Alignment in bytes. + + // Set the alignment for the local if one of the following condition is met + // 1) DECL_ALIGN_UNIT does not match alignment as per ABI specification + // 2) DECL_ALIGN is set by user. + if (DECL_ALIGN_UNIT(decl)) { + unsigned TargetAlign = getTargetData().getABITypeAlignment(Ty); + if (DECL_USER_ALIGN(decl) || TargetAlign != (unsigned)DECL_ALIGN_UNIT(decl)) + Alignment = DECL_ALIGN_UNIT(decl); + } + const char *Name; // Name of variable if (DECL_NAME(decl)) Name = IDENTIFIER_POINTER(DECL_NAME(decl)); From sabre at nondot.org Tue Sep 25 22:44:21 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Sep 2007 05:44:21 -0000 Subject: [llvm-commits] [llvm] r42341 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <200709260544.l8Q5iLbu014999@zion.cs.uiuc.edu> Author: lattner Date: Wed Sep 26 00:44:21 2007 New Revision: 42341 URL: http://llvm.org/viewvc/llvm-project?rev=42341&view=rev Log: now with more prose. Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=42341&r1=42340&r2=42341&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Wed Sep 26 00:44:21 2007 @@ -93,13 +93,14 @@
    -

    Some of the most noticable improvements this release have been in the -optimizer, speeding it up and making it more aggressive

    +

    Some of the most noticable feature improvements this release have been in the +optimizer, speeding it up and making it more aggressive. For example:

    • Owen Anderson wrote the new MemoryDependenceAnalysis pass, which provides - a lazy, caching layer on top of alias analysis. He then used it to rewrite + a lazy, caching layer on top of + AliasAnalysis. He then used it to rewrite DeadStoreElimination which resulted in significantly better compile time in common cases,
    • Owen implemented the new GVN pass, which is also based on @@ -110,9 +111,11 @@ shares some details with the new GVN pass. It is still in need of compile time tuning, and is not turned on by default.
    • Devang merged ETForest and DomTree into a single easier to use data -structure.
    • + structure. This makes it more obvious which datastructure to choose + (because there is only one) and makes the compiler more memory and time + efficient (less stuff to keep up-to-date).
    • Nick Lewycky improved loop trip count analysis to handle many more common -cases.
    • + cases.
    @@ -125,33 +128,43 @@
    +

    One of the main focuses of this release was performance tuning and bug + fixing. In addition to these, several new major changes occurred:

    +
      -
    • Dale finished up the Tail Merging optimization in the code generator, -enabling it by default. This produces smaller code that is also faster in some -cases.
    • +
    • Dale finished up the Tail Merging optimization in the code generator, and + enabled it by default. This produces smaller code that is also faster in + some cases.
    • + +
    • Christopher Lamb implemented support for virtual register sub-registers, + which can be used to better model many forms of subregisters. As an example + use, he modified the X86 backend to use this to model truncates and + extends more accurately (leading to better code).
    • Dan Gohman changed the way we represent vectors before legalization, -significantly simplifying the SelectionDAG representation for these and making -the code generator faster for vector code.
    • + significantly simplifying the SelectionDAG representation for these and + making the code generator faster for vector code. -
    • Evan remat rewrite (coalesced intervals + folding of remat'd loads) and -live intervals improvements.
    • +
    • Evan contributed a new target independent if-converter. While it is + target independent, at this point only the ARM backend uses it so far.
    • -
    • Dan Gohman contributed support for better alignment and volatility handling -in the code generator, and significantly enhanced alignment analysis for SSE -load/store instructions.
    • +
    • Evan rewrite the way the register allocator handles rematerialization, + allowing it to be much more effective on two-address targets like X86, + and taught it to fold loads away when possible (also a big win on X86).
    • -
    • Christopher Lamb virtual register sub-register support, better truncates and -extends on X86.
    • +
    • Dan Gohman contributed support for better alignment and volatility handling + in the code generator, and significantly enhanced alignment analysis for SSE + load/store instructions. With his changes, an insufficiently-aligned SSE + load instruction turns into movups, for example.
    • Duraid Madina contributed a new "bigblock" register allocator, and Roman -Levenstein contributed several big improvements. BigBlock is optimized for code -that uses very large basic blocks. It is slightly slower than the "local" -allocator, but produces much better code.
    • + Levenstein contributed several big improvements. BigBlock is optimized for + code that uses very large basic blocks. It is slightly slower than the + "local" allocator, but produces much better code.
    • David Greene refactored the register allocator to split coalescing out from -allocation, making coalescers pluggable.
    • + allocation, making coalescers pluggable.
    @@ -168,13 +181,19 @@

      -
    • Bruno Cardoso Lopes contributed initial MIPS support.
    • -
    • Bill Wendling added SSSE3 support.
    • -
    • New Target independent if converter, ARM uses it so far
    • +
    • Bruno Cardoso Lopes contributed initial MIPS support. It is sufficient to + run many small programs, but is still incomplete and is not yet + fully performant.
    • + +
    • Bill Wendling added SSSE3 support to the X86 backend.
    • +
    • Nicholas Geoffray contributed improved linux/ppc ABI and JIT support.
    • +
    • Dale Johannesen rewrote handling of 32-bit float values in the X86 backend -when using the floating point stack, fixing several nasty bugs.
    • -
    • Dan contributed rematerialization support for the X86 backend.
    • + when using the floating point stack, fixing several nasty bugs. + +
    • Dan contributed rematerialization support for the X86 backend, in addition + to several X86-specific micro optimizations.
    @@ -190,22 +209,28 @@

      -
    • Duncan and Anton exception handling in llvm-gcc 4.0/4.2
    • - -
    • Devang and Duncan: Bitfields, pragma pack
    • - -
    • Tanya implemented support for __attribute__((noinline)) in llvm-gcc, and -added support for generic variable annotations which are propagated into the -LLVM IR, e.g. "int X __attribute__((annotate("myproperty")));".
    • +
    • Duncan and Anton made significant progress chasing down a number of problems + with C++ Zero-Cost exception handling in llvm-gcc 4.0 and 4.2. It is now at + the point where it "just works" on linux/x86-32 and has partial support on + other targets.
    • + +
    • Devang and Duncan fixed a huge number of bugs relating to bitfields, pragma + pack, and variable sized fields in structures.
    • + +
    • Tanya implemented support for __attribute__((noinline)) in + llvm-gcc, and added support for generic variable annotations which are + propagated into the LLVM IR, e.g. + "int X __attribute__((annotate("myproperty")));".
    • Sheng Zhou and Christopher Lamb implemented alias analysis support for -'restrict' arguments to functions.
    • +"restrict" pointer arguments to functions. -
    • Duncan contributed support for trampolines (pointers to nested functions), -currently only supported on x86 target.
    • +
    • Duncan contributed support for trampolines (taking the address of a nested + functions), currently this is only supported in the x86 target.
    • -
    • Lauro Ramos Venancio contributed support to encode alignment info in -load and store instructions.
    • +
    • Lauro Ramos Venancio contributed support to encode alignment info in + load and store instructions, the foundation for other alignment-related + work.
    @@ -221,15 +246,22 @@

      -
    • Neil Booth APFloat, foundation for long double support that will be wrapped -up in 2.2. Dale contributed most of long double support, will be enabled in -2.2.
    • +
    • Neil Booth contributed a new "APFloat" class, which ensures that floating + point representation and constant folding is not dependent on the host + architecture that builds the application. This support is the foundation + for "long double" support that will be wrapped up in LLVM 2.2.
    • + +
    • Based on the APFloat class, Dale redesigned the internals of the ConstantFP + class and has been working on extending the core and optimizer components to + support various target-specific 'long double's. We expect this work to be + completed in LLVM 2.2.
    • -
    • LLVM now provides an LLVMBuilder class which makes it significantly easier -to create LLVM IR instructions.
    • +
    • LLVM now provides an LLVMBuilder class, which makes it significantly easier + to create LLVM IR instructions.
    • Reid contributed support for intrinsics that take arbitrary integer typed -arguments, Dan Gohman and Chandler extended it to support FP and vectors.
    • + arguments. Dan Gohman and Chandler extended it to support arbitrary + floating point arguments and vectors.
    @@ -244,10 +276,13 @@

      -
    • BrainF frontend by Sterling Stein.
    • - -
    • David Green contributed a new --enable-expensive-checks configure option -which enables STL checking, and fixed several bugs exposed by it.
    • +
    • Sterling Stein contributed a new BrainF frontend, located in llvm/examples. + This shows a some of the more modern APIs for building a front-end, and + demonstrates JIT compiler support.
    • + +
    • David Green contributed a new --enable-expensive-checks configure + option which enables STL checking, and fixed several bugs exposed by + it.
    From nicholas at mxc.ca Tue Sep 25 22:50:16 2007 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 26 Sep 2007 01:50:16 -0400 Subject: [llvm-commits] [llvm] r42341 - /llvm/trunk/docs/ReleaseNotes.html In-Reply-To: <200709260544.l8Q5iLbu014999@zion.cs.uiuc.edu> References: <200709260544.l8Q5iLbu014999@zion.cs.uiuc.edu> Message-ID: <46F9F318.3020303@mxc.ca> Chris Lattner wrote: > + a lazy, caching layer on top of > + AliasAnalysis. He then used it to rewrite Please don't place whitespace or newlines directly inside ... tags. This causes older browsers to emit a hyperlinked whitespace before the word AliasAnalysis. Nick From sabre at nondot.org Tue Sep 25 23:01:35 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Sep 2007 06:01:35 -0000 Subject: [llvm-commits] [llvm] r42342 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <200709260601.l8Q61Z8G016693@zion.cs.uiuc.edu> Author: lattner Date: Wed Sep 26 01:01:35 2007 New Revision: 42342 URL: http://llvm.org/viewvc/llvm-project?rev=42342&view=rev Log: update bugs list Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=42342&r1=42341&r2=42342&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Wed Sep 26 01:01:35 2007 @@ -353,7 +353,7 @@
  12. C++ EH support is disabled for this release.
  13. The MSIL backend is experimental.
  14. The IA64 code generator is experimental.
  15. -
  16. The Alpha JIT is experimental.
  17. +
  18. The Alpha backend is experimental.
  19. "-filetype=asm" (the default) is the only supported value for the -filetype llc option.
  20. @@ -370,6 +370,9 @@ @@ -479,6 +482,13 @@ From sabre at nondot.org Tue Sep 25 23:04:16 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Sep 2007 06:04:16 -0000 Subject: [llvm-commits] [llvm] r42343 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <200709260604.l8Q64G2b016927@zion.cs.uiuc.edu> Author: lattner Date: Wed Sep 26 01:04:15 2007 New Revision: 42343 URL: http://llvm.org/viewvc/llvm-project?rev=42343&view=rev Log: we support attribute(noinline) now :) Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=42343&r1=42342&r2=42343&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Wed Sep 26 01:04:15 2007 @@ -540,11 +540,11 @@ Supported: alias, always_inline, cdecl, constructor, destructor, deprecated, fastcall, format, - format_arg, non_null, noreturn, regparm + format_arg, non_null, noinline, noreturn, regparm section, stdcall, unused, used, visibility, warn_unused_result, weak
    - Ignored: noinline, pure, const, nothrow, + Ignored: pure, const, nothrow, malloc, no_instrument_function
From sabre at nondot.org Tue Sep 25 23:10:47 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Sep 2007 06:10:47 -0000 Subject: [llvm-commits] [llvm] r42344 - /llvm/trunk/Makefile.rules Message-ID: <200709260610.l8Q6Alui017665@zion.cs.uiuc.edu> Author: lattner Date: Wed Sep 26 01:10:47 2007 New Revision: 42344 URL: http://llvm.org/viewvc/llvm-project?rev=42344&view=rev Log: noone uses etags. Connected to PR1601 Modified: llvm/trunk/Makefile.rules Modified: llvm/trunk/Makefile.rules URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.rules?rev=42344&r1=42343&r2=42344&view=diff ============================================================================== --- llvm/trunk/Makefile.rules (original) +++ llvm/trunk/Makefile.rules Wed Sep 26 01:10:47 2007 @@ -23,7 +23,7 @@ LocalTargets := all-local clean-local clean-all-local check-local \ install-local printvars uninstall-local \ install-bytecode-local -TopLevelTargets := check dist dist-check dist-clean tags dist-gzip dist-bzip2 \ +TopLevelTargets := check dist dist-check dist-clean dist-gzip dist-bzip2 \ dist-zip UserTargets := $(RecursiveTargets) $(LocalTargets) $(TopLevelTargets) InternalTargets := preconditions distdir dist-hook @@ -1439,25 +1439,6 @@ clean-all-local:: -$(Verb) $(RM) -rf Debug Release Profile -# Build tags database for Emacs/Xemacs: -tags:: TAGS CTAGS - -TAGS: - find $(PROJ_SRC_ROOT)/include $(PROJ_SRC_ROOT)/lib \ - $(PROJ_SRC_ROOT)/tools $(PROJ_SRC_ROOT)/examples \ - $(PROJ_OBJ_ROOT)/include $(PROJ_OBJ_ROOT)/lib \ - $(PROJ_OBJ_ROOT)/tools $(PROJ_OBJ_ROOT)/examples \ - -name '*.cpp' -o -name '*.h' | \ - $(ETAGS) $(ETAGSFLAGS) - - -CTAGS: - find $(PROJ_SRC_ROOT)/include $(PROJ_SRC_ROOT)/lib \ - $(PROJ_SRC_ROOT)/tools $(PROJ_SRC_ROOT)/examples \ - $(PROJ_OBJ_ROOT)/include $(PROJ_OBJ_ROOT)/lib \ - $(PROJ_OBJ_ROOT)/tools $(PROJ_OBJ_ROOT)/examples \ - \( -name '*.cpp' -o -name '*.h' \) -print | \ - ctags -ImtT -o $(PROJ_OBJ_ROOT)/CTAGS -L - - ############################################################################### # DEPENDENCIES: Include the dependency files if we should From sabre at nondot.org Tue Sep 25 23:15:49 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Sep 2007 06:15:49 -0000 Subject: [llvm-commits] [llvm] r42345 - /llvm/trunk/lib/Target/X86/README-SSE.txt Message-ID: <200709260615.l8Q6FoeW018242@zion.cs.uiuc.edu> Author: lattner Date: Wed Sep 26 01:15:48 2007 New Revision: 42345 URL: http://llvm.org/viewvc/llvm-project?rev=42345&view=rev Log: move PR1264 here. Modified: llvm/trunk/lib/Target/X86/README-SSE.txt Modified: llvm/trunk/lib/Target/X86/README-SSE.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README-SSE.txt?rev=42345&r1=42344&r2=42345&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README-SSE.txt (original) +++ llvm/trunk/lib/Target/X86/README-SSE.txt Wed Sep 26 01:15:48 2007 @@ -631,7 +631,7 @@ //===---------------------------------------------------------------------===// -We should materialize vecetor constants like "all ones" and "signbit" with +We should materialize vector constants like "all ones" and "signbit" with code like: cmpeqps xmm1, xmm1 ; xmm1 = all-ones @@ -644,3 +644,30 @@ ABS/NEG/copysign etc. //===---------------------------------------------------------------------===// + +"converting 64-bit constant pool entry to 32-bit not necessarily beneficial" +http://llvm.org/PR1264 + +For this test case: + +define double @foo(double %x) { + %y = mul double %x, 5.000000e-01 + ret double %y +} + +llc -march=x86-64 currently produces a 32-bit constant pool entry and this code: + + cvtss2sd .LCPI1_0(%rip), %xmm1 + mulsd %xmm1, %xmm0 + +instead of just using a 64-bit constant pool entry with this: + + mulsd .LCPI1_0(%rip), %xmm0 + +This is due to the code in ExpandConstantFP in LegalizeDAG.cpp. It notices that +x86-64 indeed has an instruction to load a 32-bit float from memory and convert +it into a 64-bit float in a register, however it doesn't notice that this isn't +beneficial because it prevents the load from being folded into the multiply. + +//===---------------------------------------------------------------------===// + From evan.cheng at apple.com Tue Sep 25 23:25:56 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Sep 2007 06:25:56 -0000 Subject: [llvm-commits] [llvm] r42346 - in /llvm/trunk: include/llvm/Target/ lib/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/X86/ Message-ID: <200709260625.l8Q6Pv82019467@zion.cs.uiuc.edu> Author: evancheng Date: Wed Sep 26 01:25:56 2007 New Revision: 42346 URL: http://llvm.org/viewvc/llvm-project?rev=42346&view=rev Log: Allow copyRegToReg to emit cross register classes copies. Tested with "make check"! Modified: llvm/trunk/include/llvm/Target/MRegisterInfo.h llvm/trunk/lib/CodeGen/LowerSubregs.cpp llvm/trunk/lib/CodeGen/PHIElimination.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp llvm/trunk/lib/CodeGen/VirtRegMap.cpp llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.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=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/MRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/MRegisterInfo.h Wed Sep 26 01:25:56 2007 @@ -506,7 +506,8 @@ virtual void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const = 0; + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const = 0; /// reMaterialize - Re-issue the specified 'original' instruction at the /// specific location targeting a new destination register. Modified: llvm/trunk/lib/CodeGen/LowerSubregs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LowerSubregs.cpp?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LowerSubregs.cpp (original) +++ llvm/trunk/lib/CodeGen/LowerSubregs.cpp Wed Sep 26 01:25:56 2007 @@ -88,7 +88,7 @@ assert(TRC == getPhysicalRegisterRegClass(MRI, SrcReg) && "Extract subreg and Dst must be of same register class"); - MRI.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC); + MRI.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC, TRC); MachineBasicBlock::iterator dMI = MI; DOUT << "subreg: " << *(--dMI); } @@ -157,7 +157,7 @@ } else { TRC1 = MF.getSSARegMap()->getRegClass(InsReg); } - MRI.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1); + MRI.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1, TRC1); #ifndef NDEBUG MachineBasicBlock::iterator dMI = MI; @@ -184,7 +184,7 @@ assert(TRC0 == getPhysicalRegisterRegClass(MRI, SrcReg) && "Insert superreg and Dst must be of same register class"); - MRI.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC0); + MRI.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC0, TRC0); #ifndef NDEBUG MachineBasicBlock::iterator dMI = MI; @@ -206,7 +206,7 @@ } else { TRC1 = MF.getSSARegMap()->getRegClass(InsReg); } - MRI.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1); + MRI.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1, TRC1); #ifndef NDEBUG MachineBasicBlock::iterator dMI = MI; Modified: llvm/trunk/lib/CodeGen/PHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIElimination.cpp?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/PHIElimination.cpp Wed Sep 26 01:25:56 2007 @@ -135,7 +135,7 @@ // into the phi node destination. // const MRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); - RegInfo->copyRegToReg(MBB, AfterPHIsIt, DestReg, IncomingReg, RC); + RegInfo->copyRegToReg(MBB, AfterPHIsIt, DestReg, IncomingReg, RC, RC); // Update live variable information if there is any... LiveVariables *LV = getAnalysisToUpdate(); @@ -200,7 +200,7 @@ MachineBasicBlock::iterator I = opBlock.getFirstTerminator(); // Insert the copy. - RegInfo->copyRegToReg(opBlock, I, IncomingReg, SrcReg, RC); + RegInfo->copyRegToReg(opBlock, I, IncomingReg, SrcReg, RC, RC); // Now update live variable information if we have it. Otherwise we're done if (!LV) continue; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Wed Sep 26 01:25:56 2007 @@ -365,7 +365,7 @@ } else { // Create the reg, emit the copy. VRBase = RegMap->createVirtualRegister(TRC); - MRI->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, TRC); + MRI->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, TRC, TRC); } if (InstanceNo > 0) @@ -769,7 +769,7 @@ TRC = getPhysicalRegisterRegClass(MRI, Node->getOperand(2).getValueType(), InReg); - MRI->copyRegToReg(*BB, BB->end(), DestReg, InReg, TRC); + MRI->copyRegToReg(*BB, BB->end(), DestReg, InReg, TRC, TRC); } break; } @@ -854,9 +854,11 @@ if (&MF.front() == BB && MF.livein_begin() != MF.livein_end()) { for (MachineFunction::livein_iterator LI = MF.livein_begin(), E = MF.livein_end(); LI != E; ++LI) - if (LI->second) + if (LI->second) { + const TargetRegisterClass *RC = RegMap->getRegClass(LI->second); MRI->copyRegToReg(*MF.begin(), MF.begin()->end(), LI->second, - LI->first, RegMap->getRegClass(LI->second)); + LI->first, RC, RC); + } } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp Wed Sep 26 01:25:56 2007 @@ -684,9 +684,11 @@ if (&MF.front() == BB && MF.livein_begin() != MF.livein_end()) { for (MachineFunction::livein_iterator LI = MF.livein_begin(), E = MF.livein_end(); LI != E; ++LI) - if (LI->second) + if (LI->second) { + const TargetRegisterClass *RC = RegMap->getRegClass(LI->second); MRI->copyRegToReg(*MF.begin(), MF.begin()->end(), LI->second, - LI->first, RegMap->getRegClass(LI->second)); + LI->first, RC, RC); + } } DenseMap VRBaseMap; Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp (original) +++ llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Wed Sep 26 01:25:56 2007 @@ -192,7 +192,7 @@ InstructionRearranged: const TargetRegisterClass* rc = MF.getSSARegMap()->getRegClass(regA); - MRI.copyRegToReg(*mbbi, mi, regA, regB, rc); + MRI.copyRegToReg(*mbbi, mi, regA, regB, rc, rc); MachineBasicBlock::iterator prevMi = prior(mi); DOUT << "\t\tprepend:\t"; DEBUG(prevMi->print(*cerr.stream(), &TM)); Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Wed Sep 26 01:25:56 2007 @@ -926,7 +926,7 @@ const TargetRegisterClass* RC = MF.getSSARegMap()->getRegClass(VirtReg); MF.setPhysRegUsed(DesignatedReg); ReusedOperands.markClobbered(DesignatedReg); - MRI->copyRegToReg(MBB, &MI, DesignatedReg, PhysReg, RC); + MRI->copyRegToReg(MBB, &MI, DesignatedReg, PhysReg, RC, RC); MachineInstr *CopyMI = prior(MII); UpdateKills(*CopyMI, RegKills, KillOps); @@ -1009,8 +1009,9 @@ if (unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SS)) { DOUT << "Promoted Load To Copy: " << MI; if (DestReg != InReg) { - MRI->copyRegToReg(MBB, &MI, DestReg, InReg, - MF.getSSARegMap()->getRegClass(VirtReg)); + 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). Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Wed Sep 26 01:25:56 2007 @@ -183,8 +183,14 @@ void ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const { - if (RC == ARM::GPRRegisterClass) { + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const { + if (DestRC != SrcRC) { + cerr << "Not yet supported!"; + abort(); + } + + if (DestRC == ARM::GPRRegisterClass) { MachineFunction &MF = *MBB.getParent(); ARMFunctionInfo *AFI = MF.getInfo(); if (AFI->isThumbFunction()) @@ -192,10 +198,10 @@ else BuildMI(MBB, I, TII.get(ARM::MOVr), DestReg).addReg(SrcReg) .addImm((int64_t)ARMCC::AL).addReg(0).addReg(0); - } else if (RC == ARM::SPRRegisterClass) + } else if (DestRC == ARM::SPRRegisterClass) BuildMI(MBB, I, TII.get(ARM::FCPYS), DestReg).addReg(SrcReg) .addImm((int64_t)ARMCC::AL).addReg(0); - else if (RC == ARM::DPRRegisterClass) + else if (DestRC == ARM::DPRRegisterClass) BuildMI(MBB, I, TII.get(ARM::FCPYD), DestReg).addReg(SrcReg) .addImm((int64_t)ARMCC::AL).addReg(0); else Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h Wed Sep 26 01:25:56 2007 @@ -58,7 +58,8 @@ void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const; + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const; void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, const MachineInstr *Orig) const; Modified: llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp Wed Sep 26 01:25:56 2007 @@ -141,13 +141,19 @@ void AlphaRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const { + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const { //cerr << "copyRegToReg " << DestReg << " <- " << SrcReg << "\n"; - if (RC == Alpha::GPRCRegisterClass) { + if (DestRC != SrcRC) { + cerr << "Not yet supported!"; + abort(); + } + + if (DestRC == Alpha::GPRCRegisterClass) { BuildMI(MBB, MI, TII.get(Alpha::BISr), DestReg).addReg(SrcReg).addReg(SrcReg); - } else if (RC == Alpha::F4RCRegisterClass) { + } else if (DestRC == Alpha::F4RCRegisterClass) { BuildMI(MBB, MI, TII.get(Alpha::CPYSS), DestReg).addReg(SrcReg).addReg(SrcReg); - } else if (RC == Alpha::F8RCRegisterClass) { + } else if (DestRC == Alpha::F8RCRegisterClass) { BuildMI(MBB, MI, TII.get(Alpha::CPYST), DestReg).addReg(SrcReg).addReg(SrcReg); } else { cerr << "Attempt to copy register that is not GPR or FPR"; Modified: llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h (original) +++ llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h Wed Sep 26 01:25:56 2007 @@ -48,7 +48,8 @@ void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const; + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const; void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, const MachineInstr *Orig) const; Modified: llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp Wed Sep 26 01:25:56 2007 @@ -83,9 +83,14 @@ void IA64RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const { + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const { + if (DestRC != SrcRC) { + cerr << "Not yet supported!"; + abort(); + } - if(RC == IA64::PRRegisterClass ) // if a bool, we use pseudocode + if(DestRC == IA64::PRRegisterClass ) // if a bool, we use pseudocode // (SrcReg) DestReg = cmp.eq.unc(r0, r0) BuildMI(MBB, MI, TII.get(IA64::PCMPEQUNC), DestReg) .addReg(IA64::r0).addReg(IA64::r0).addReg(SrcReg); Modified: llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h (original) +++ llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h Wed Sep 26 01:25:56 2007 @@ -42,7 +42,8 @@ void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const; + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const; void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, const MachineInstr *Orig) const; Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp Wed Sep 26 01:25:56 2007 @@ -109,9 +109,15 @@ void MipsRegisterInfo:: copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const { - if (RC == Mips::CPURegsRegisterClass) + if (DestRC != SrcRC) { + cerr << "Not yet supported!"; + abort(); + } + + if (DestRC == Mips::CPURegsRegisterClass) BuildMI(MBB, I, TII.get(Mips::ADDu), DestReg).addReg(Mips::ZERO) .addReg(SrcReg); else Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h Wed Sep 26 01:25:56 2007 @@ -55,7 +55,8 @@ void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const; + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const; const unsigned *getCalleeSavedRegs(const MachineFunction* MF = 0) const; Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Wed Sep 26 01:25:56 2007 @@ -226,18 +226,24 @@ void PPCRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const { - if (RC == PPC::GPRCRegisterClass) { + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const { + if (DestRC != SrcRC) { + cerr << "Not yet supported!"; + abort(); + } + + if (DestRC == PPC::GPRCRegisterClass) { BuildMI(MBB, MI, TII.get(PPC::OR), DestReg).addReg(SrcReg).addReg(SrcReg); - } else if (RC == PPC::G8RCRegisterClass) { + } else if (DestRC == PPC::G8RCRegisterClass) { BuildMI(MBB, MI, TII.get(PPC::OR8), DestReg).addReg(SrcReg).addReg(SrcReg); - } else if (RC == PPC::F4RCRegisterClass) { + } else if (DestRC == PPC::F4RCRegisterClass) { BuildMI(MBB, MI, TII.get(PPC::FMRS), DestReg).addReg(SrcReg); - } else if (RC == PPC::F8RCRegisterClass) { + } else if (DestRC == PPC::F8RCRegisterClass) { BuildMI(MBB, MI, TII.get(PPC::FMRD), DestReg).addReg(SrcReg); - } else if (RC == PPC::CRRCRegisterClass) { + } else if (DestRC == PPC::CRRCRegisterClass) { BuildMI(MBB, MI, TII.get(PPC::MCRF), DestReg).addReg(SrcReg); - } else if (RC == PPC::VRRCRegisterClass) { + } else if (DestRC == PPC::VRRCRegisterClass) { BuildMI(MBB, MI, TII.get(PPC::VOR), DestReg).addReg(SrcReg).addReg(SrcReg); } else { cerr << "Attempt to copy register that is not GPR or FPR"; Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h Wed Sep 26 01:25:56 2007 @@ -47,7 +47,8 @@ void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const; + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const; void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, const MachineInstr *Orig) const; Modified: llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp Wed Sep 26 01:25:56 2007 @@ -65,12 +65,18 @@ void SparcRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const { - if (RC == SP::IntRegsRegisterClass) + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const { + if (DestRC != SrcRC) { + cerr << "Not yet supported!"; + abort(); + } + + if (DestRC == SP::IntRegsRegisterClass) BuildMI(MBB, I, TII.get(SP::ORrr), DestReg).addReg(SP::G0).addReg(SrcReg); - else if (RC == SP::FPRegsRegisterClass) + else if (DestRC == SP::FPRegsRegisterClass) BuildMI(MBB, I, TII.get(SP::FMOVS), DestReg).addReg(SrcReg); - else if (RC == SP::DFPRegsRegisterClass) + else if (DestRC == SP::DFPRegsRegisterClass) BuildMI(MBB, I, TII.get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD),DestReg) .addReg(SrcReg); else Modified: llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h (original) +++ llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h Wed Sep 26 01:25:56 2007 @@ -42,7 +42,8 @@ void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const; + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const; void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, const MachineInstr *Orig) const; Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Wed Sep 26 01:25:56 2007 @@ -231,33 +231,39 @@ void X86RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const { + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const { + if (DestRC != SrcRC) { + cerr << "Not yet supported!"; + abort(); + } + unsigned Opc; - if (RC == &X86::GR64RegClass) { + if (DestRC == &X86::GR64RegClass) { Opc = X86::MOV64rr; - } else if (RC == &X86::GR32RegClass) { + } else if (DestRC == &X86::GR32RegClass) { Opc = X86::MOV32rr; - } else if (RC == &X86::GR16RegClass) { + } else if (DestRC == &X86::GR16RegClass) { Opc = X86::MOV16rr; - } else if (RC == &X86::GR8RegClass) { + } else if (DestRC == &X86::GR8RegClass) { Opc = X86::MOV8rr; - } else if (RC == &X86::GR32_RegClass) { + } else if (DestRC == &X86::GR32_RegClass) { Opc = X86::MOV32_rr; - } else if (RC == &X86::GR16_RegClass) { + } else if (DestRC == &X86::GR16_RegClass) { Opc = X86::MOV16_rr; - } else if (RC == &X86::RFP32RegClass) { + } else if (DestRC == &X86::RFP32RegClass) { Opc = X86::MOV_Fp3232; - } else if (RC == &X86::RFP64RegClass || RC == &X86::RSTRegClass) { + } else if (DestRC == &X86::RFP64RegClass || DestRC == &X86::RSTRegClass) { Opc = X86::MOV_Fp6464; - } else if (RC == &X86::RFP80RegClass) { + } else if (DestRC == &X86::RFP80RegClass) { Opc = X86::MOV_Fp8080; - } else if (RC == &X86::FR32RegClass) { + } else if (DestRC == &X86::FR32RegClass) { Opc = X86::FsMOVAPSrr; - } else if (RC == &X86::FR64RegClass) { + } else if (DestRC == &X86::FR64RegClass) { Opc = X86::FsMOVAPDrr; - } else if (RC == &X86::VR128RegClass) { + } else if (DestRC == &X86::VR128RegClass) { Opc = X86::MOVAPSrr; - } else if (RC == &X86::VR64RegClass) { + } else if (DestRC == &X86::VR64RegClass) { Opc = X86::MMX_MOVQ64rr; } else { assert(0 && "Unknown regclass"); Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.h?rev=42346&r1=42345&r2=42346&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.h Wed Sep 26 01:25:56 2007 @@ -78,7 +78,8 @@ void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const; + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const; void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, const MachineInstr *Orig) const; From sabre at nondot.org Tue Sep 25 23:29:31 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Sep 2007 06:29:31 -0000 Subject: [llvm-commits] [llvm] r42347 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200709260629.l8Q6TVUR019703@zion.cs.uiuc.edu> Author: lattner Date: Wed Sep 26 01:29:31 2007 New Revision: 42347 URL: http://llvm.org/viewvc/llvm-project?rev=42347&view=rev Log: move PR1160 here. 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=42347&r1=42346&r2=42347&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Wed Sep 26 01:29:31 2007 @@ -1208,3 +1208,34 @@ Re-materialize MOV32r0 etc. with xor instead of changing them to moves if the condition register is dead. xor reg reg is shorter than mov reg, #0. + +//===---------------------------------------------------------------------===// + +We aren't matching RMW instructions aggressively +enough. Here's a reduced testcase (more in PR1160): + +define void @test(i32* %huge_ptr, i32* %target_ptr) { + %A = load i32* %huge_ptr ; [#uses=1] + %B = load i32* %target_ptr ; [#uses=1] + %C = or i32 %A, %B ; [#uses=1] + store i32 %C, i32* %target_ptr + ret void +} + +$ llvm-as < t.ll | llc -march=x86-64 + +_test: + movl (%rdi), %eax + orl (%rsi), %eax + movl %eax, (%rsi) + ret + +That should be something like: + +_test: + movl (%rdi), %eax + orl %eax, (%rsi) + ret + +//===---------------------------------------------------------------------===// + From evan.cheng at apple.com Tue Sep 25 23:38:29 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Sep 2007 06:38:29 -0000 Subject: [llvm-commits] [llvm] r42348 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.td X86InstrX86-64.td Message-ID: <200709260638.l8Q6cUwX020616@zion.cs.uiuc.edu> Author: evancheng Date: Wed Sep 26 01:38:29 2007 New Revision: 42348 URL: http://llvm.org/viewvc/llvm-project?rev=42348&view=rev Log: Typos: POPQ -> POPFQ, POPD -> POPFD. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td llvm/trunk/lib/Target/X86/X86InstrX86-64.td Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=42348&r1=42347&r2=42348&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed Sep 26 01:38:29 2007 @@ -430,7 +430,7 @@ } let Defs = [ESP, EFLAGS], Uses = [ESP] in -def POPD : I<0x9D, RawFrm, (outs), (ins), "popfd", []>; +def POPFD : I<0x9D, RawFrm, (outs), (ins), "popfd", []>; let Defs = [ESP], Uses = [ESP, EFLAGS] in def PUSHFD : I<0x9C, RawFrm, (outs), (ins), "pushfd", []>; 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=42348&r1=42347&r2=42348&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrX86-64.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrX86-64.td Wed Sep 26 01:38:29 2007 @@ -124,7 +124,7 @@ } let Defs = [RSP, EFLAGS], Uses = [RSP] in -def POPQ : I<0x9D, RawFrm, (outs), (ins), "popfq", []>, REX_W; +def POPFQ : I<0x9D, RawFrm, (outs), (ins), "popfq", []>, REX_W; let Defs = [RSP], Uses = [RSP, EFLAGS] in def PUSHFQ : I<0x9C, RawFrm, (outs), (ins), "pushfq", []>; From sabre at nondot.org Tue Sep 25 23:39:00 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Sep 2007 06:39:00 -0000 Subject: [llvm-commits] [llvm] r42349 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <200709260639.l8Q6d0WK020684@zion.cs.uiuc.edu> Author: lattner Date: Wed Sep 26 01:38:59 2007 New Revision: 42349 URL: http://llvm.org/viewvc/llvm-project?rev=42349&view=rev Log: make old crappy browsers produce less crappy output :) Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=42349&r1=42348&r2=42349&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Wed Sep 26 01:38:59 2007 @@ -99,8 +99,8 @@
  • Owen Anderson wrote the new MemoryDependenceAnalysis pass, which provides - a lazy, caching layer on top of - AliasAnalysis. He then used it to rewrite + a lazy, caching layer on top of AliasAnalysis. He then used it to rewrite DeadStoreElimination which resulted in significantly better compile time in common cases,
  • Owen implemented the new GVN pass, which is also based on From baldrick at free.fr Wed Sep 26 00:28:21 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 Sep 2007 07:28:21 -0000 Subject: [llvm-commits] [llvm] r42350 - in /llvm/trunk/test/CFrontend: 2007-06-05-NoInlineAttribute.c 2007-06-15-AnnotateAttribute.c 2007-07-29-RestrictPtrArg.c 2007-09-20-GcrootAttribute.c Message-ID: <200709260728.l8Q7SL2T023327@zion.cs.uiuc.edu> Author: baldrick Date: Wed Sep 26 02:28:20 2007 New Revision: 42350 URL: http://llvm.org/viewvc/llvm-project?rev=42350&view=rev Log: Test the C front-end, not the C++ front-end. Modified: llvm/trunk/test/CFrontend/2007-06-05-NoInlineAttribute.c llvm/trunk/test/CFrontend/2007-06-15-AnnotateAttribute.c llvm/trunk/test/CFrontend/2007-07-29-RestrictPtrArg.c llvm/trunk/test/CFrontend/2007-09-20-GcrootAttribute.c Modified: llvm/trunk/test/CFrontend/2007-06-05-NoInlineAttribute.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/2007-06-05-NoInlineAttribute.c?rev=42350&r1=42349&r2=42350&view=diff ============================================================================== --- llvm/trunk/test/CFrontend/2007-06-05-NoInlineAttribute.c (original) +++ llvm/trunk/test/CFrontend/2007-06-05-NoInlineAttribute.c Wed Sep 26 02:28:20 2007 @@ -1,4 +1,4 @@ -// RUN: %llvmgxx -c -emit-llvm %s -o - | llvm-dis | grep llvm.noinline +// RUN: %llvmgcc -c -emit-llvm %s -o - | llvm-dis | grep llvm.noinline static int bar(int x, int y) __attribute__((noinline)); Modified: llvm/trunk/test/CFrontend/2007-06-15-AnnotateAttribute.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/2007-06-15-AnnotateAttribute.c?rev=42350&r1=42349&r2=42350&view=diff ============================================================================== --- llvm/trunk/test/CFrontend/2007-06-15-AnnotateAttribute.c (original) +++ llvm/trunk/test/CFrontend/2007-06-15-AnnotateAttribute.c Wed Sep 26 02:28:20 2007 @@ -1,5 +1,5 @@ -// RUN: %llvmgxx -c -emit-llvm %s -o - | llvm-dis | grep llvm.global.annotations -// RUN: %llvmgxx -c -emit-llvm %s -o - | llvm-dis | grep llvm.var.annotation | count 3 +// RUN: %llvmgcc -c -emit-llvm %s -o - | llvm-dis | grep llvm.global.annotations +// RUN: %llvmgcc -c -emit-llvm %s -o - | llvm-dis | grep llvm.var.annotation | count 3 #include Modified: llvm/trunk/test/CFrontend/2007-07-29-RestrictPtrArg.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/2007-07-29-RestrictPtrArg.c?rev=42350&r1=42349&r2=42350&view=diff ============================================================================== --- llvm/trunk/test/CFrontend/2007-07-29-RestrictPtrArg.c (original) +++ llvm/trunk/test/CFrontend/2007-07-29-RestrictPtrArg.c Wed Sep 26 02:28:20 2007 @@ -1,4 +1,4 @@ -// RUN: %llvmgxx -c -emit-llvm %s -o - | llvm-dis | grep noalias +// RUN: %llvmgcc -c -emit-llvm %s -o - | llvm-dis | grep noalias void foo(int * __restrict myptr1, int * myptr2) { myptr1[0] = 0; Modified: llvm/trunk/test/CFrontend/2007-09-20-GcrootAttribute.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/2007-09-20-GcrootAttribute.c?rev=42350&r1=42349&r2=42350&view=diff ============================================================================== --- llvm/trunk/test/CFrontend/2007-09-20-GcrootAttribute.c (original) +++ llvm/trunk/test/CFrontend/2007-09-20-GcrootAttribute.c Wed Sep 26 02:28:20 2007 @@ -1,5 +1,5 @@ -// RUN: %llvmgxx -S -emit-llvm %s -o - | grep llvm.gcroot -// RUN: %llvmgxx -S -emit-llvm %s -o - | grep llvm.gcroot | count 6 +// RUN: %llvmgcc -S -emit-llvm %s -o - | grep llvm.gcroot +// RUN: %llvmgcc -S -emit-llvm %s -o - | grep llvm.gcroot | count 6 typedef struct foo_s { From asl at math.spbu.ru Wed Sep 26 00:36:55 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Wed, 26 Sep 2007 07:36:55 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42351 - /llvm-gcc-4.0/trunk/gcc/config/freebsd.h Message-ID: <200709260736.l8Q7auMM027675@zion.cs.uiuc.edu> Author: asl Date: Wed Sep 26 02:36:55 2007 New Revision: 42351 URL: http://llvm.org/viewvc/llvm-project?rev=42351&view=rev Log: FreeBSD really supports #pragma pack(push). This fixes PR1702 Modified: llvm-gcc-4.0/trunk/gcc/config/freebsd.h Modified: llvm-gcc-4.0/trunk/gcc/config/freebsd.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/config/freebsd.h?rev=42351&r1=42350&r2=42351&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/config/freebsd.h (original) +++ llvm-gcc-4.0/trunk/gcc/config/freebsd.h Wed Sep 26 02:36:55 2007 @@ -85,3 +85,7 @@ This enables the test coverage code to use file locking when exiting a program, which avoids race conditions if the program has forked. */ #define TARGET_HAS_F_SETLKW + +/* LLVM LOCAL begin */ +#define HANDLE_PRAGMA_PACK_PUSH_POP +/* LLVM LOCAL end */ From asl at math.spbu.ru Wed Sep 26 00:40:13 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Wed, 26 Sep 2007 07:40:13 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r42352 - /llvm-gcc-4.2/trunk/gcc/config/freebsd.h Message-ID: <200709260740.l8Q7eDN8029839@zion.cs.uiuc.edu> Author: asl Date: Wed Sep 26 02:40:13 2007 New Revision: 42352 URL: http://llvm.org/viewvc/llvm-project?rev=42352&view=rev Log: FreeBSD really supports #pragma pack(push). This fixes PR1702 Modified: llvm-gcc-4.2/trunk/gcc/config/freebsd.h Modified: llvm-gcc-4.2/trunk/gcc/config/freebsd.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/freebsd.h?rev=42352&r1=42351&r2=42352&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/freebsd.h (original) +++ llvm-gcc-4.2/trunk/gcc/config/freebsd.h Wed Sep 26 02:40:13 2007 @@ -85,3 +85,7 @@ This enables the test coverage code to use file locking when exiting a program, which avoids race conditions if the program has forked. */ #define TARGET_POSIX_IO + +/* LLVM LOCAL begin */ +#define HANDLE_PRAGMA_PACK_PUSH_POP +/* LLVM LOCAL end */ From asl at math.spbu.ru Wed Sep 26 02:06:00 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Wed, 26 Sep 2007 09:06:00 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42353 - in /llvm-gcc-4.0/trunk/gcc: config/alpha/unicosmk.h config/darwin.h objc/objc-act.c Message-ID: <200709260906.l8Q960Pr001546@zion.cs.uiuc.edu> Author: asl Date: Wed Sep 26 04:05:59 2007 New Revision: 42353 URL: http://llvm.org/viewvc/llvm-project?rev=42353&view=rev Log: Unbreak objc on non-darwin Modified: llvm-gcc-4.0/trunk/gcc/config/alpha/unicosmk.h llvm-gcc-4.0/trunk/gcc/config/darwin.h llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Modified: llvm-gcc-4.0/trunk/gcc/config/alpha/unicosmk.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/config/alpha/unicosmk.h?rev=42353&r1=42352&r2=42353&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/config/alpha/unicosmk.h (original) +++ llvm-gcc-4.0/trunk/gcc/config/alpha/unicosmk.h Wed Sep 26 04:05:59 2007 @@ -96,7 +96,7 @@ /* The stack frame grows downward. */ -#define FRAME_GROWS_DOWNWARD +#define FRAME_GROWS_DOWNWARD 1 /* Define the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. This is somewhat Modified: llvm-gcc-4.0/trunk/gcc/config/darwin.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/config/darwin.h?rev=42353&r1=42352&r2=42353&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/config/darwin.h (original) +++ llvm-gcc-4.0/trunk/gcc/config/darwin.h Wed Sep 26 04:05:59 2007 @@ -790,6 +790,20 @@ error ("Mac OS X version 10.5 or later is needed for zerocost-exceptions"); \ } while (0) /* APPLE LOCAL end radar 5023725 */ + +/* LLVM LOCAL begin */ +/* APPLE LOCAL begin radar 4590191 */ +#undef OBJC_FLAG_SJLJ_EXCEPTIONS +#define OBJC_FLAG_SJLJ_EXCEPTIONS \ + do { \ + if (darwin_macosx_version_min \ + && strverscmp (darwin_macosx_version_min, "10.3") < 0) \ + warning (0, "Mac OS X version 10.3 or later is needed instead of %s for objc/obj-c++ exceptions", \ + darwin_macosx_version_min); \ + } while(0) +/* APPLE LOCAL end radar 4590191 */ +/* LLVM LOCAL end */ + /* APPLE LOCAL begin radar 4862848 */ #undef OBJC_FLAG_OBJC_ABI #define OBJC_FLAG_OBJC_ABI \ 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=42353&r1=42352&r2=42353&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Wed Sep 26 04:05:59 2007 @@ -124,6 +124,13 @@ #ifndef OBJC_FLAG_ZEROCOST_EXCEPTIONS #define OBJC_FLAG_ZEROCOST_EXCEPTIONS #endif +/* LLVM LOCAL begin */ +/* APPLE LOCAL begin radar 4590191 */ +#ifndef OBJC_FLAG_SJLJ_EXCEPTIONS +#define OBJC_FLAG_SJLJ_EXCEPTIONS +#endif +/* APPLE LOCAL end radar 4590191 */ +/* LLVM LOCAL end */ /* APPLE LOCAL end radar 5023725 */ /* APPLE LOCAL begin radar 4531086 */ #ifndef OBJC_WARN_OBJC2_FEATURES @@ -7638,10 +7645,9 @@ /* APPLE LOCAL begin radar 4590191 */ if (flag_objc_sjlj_exceptions) { - if (darwin_macosx_version_min - && strverscmp (darwin_macosx_version_min, "10.3") < 0) - warning ("Mac OS X version 10.3 or later is needed instead of %s for objc/obj-c++ exceptions", - darwin_macosx_version_min); + /* LLVM LOCAL begin */ + OBJC_FLAG_SJLJ_EXCEPTIONS; + /* LLVM LOCAL end */ /* APPLE LOCAL end radar 4590191 */ /* APPLE LOCAL radar 4512786. */ /* code removed */ @@ -18151,7 +18157,7 @@ set_user_assembler_name(decl, string); /* Let optimizer know that this decl is not removable. */ DECL_PRESERVE_P (decl) = 1; -#endif ENABLE_LLVM +#endif /* APPLE LOCAL end LLVM */ pushdecl (decl); @@ -18170,7 +18176,7 @@ /* This decl's name is special. Ask llvm to not add leading underscore by setting it as a user supplied asm name. */ set_user_assembler_name(decl, string); -#endif ENABLE_LLVM +#endif /* APPLE LOCAL end LLVM */ pushdecl (decl); @@ -18254,7 +18260,7 @@ set_user_assembler_name(decl, string); /* Let optimizer know that this decl is not removable. */ DECL_PRESERVE_P (decl) = 1; -#endif ENABLE_LLVM +#endif /* APPLE LOCAL end LLVM */ DECL_INITIAL (decl) = init; assemble_variable (decl, 1, 0, 0); @@ -18317,7 +18323,7 @@ /* Let optimizer know that this decl is not removable. */ set_user_assembler_name(decl, IDENTIFIER_POINTER (DECL_NAME(decl))); DECL_PRESERVE_P (decl) = 1; -#endif ENABLE_LLVM +#endif /* APPLE LOCAL end LLVM */ assemble_variable (decl, 1, 0, 0); } From gordonhenriksen at mac.com Wed Sep 26 05:31:55 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Wed, 26 Sep 2007 08:31:55 -0400 Subject: [llvm-commits] [llvm] r42342 - /llvm/trunk/docs/ReleaseNotes.html In-Reply-To: <200709260601.l8Q61Z8G016693@zion.cs.uiuc.edu> References: <200709260601.l8Q61Z8G016693@zion.cs.uiuc.edu> Message-ID: <9258D4DF-C838-4DF5-96C3-424D9828532F@mac.com> On Sep 26, 2007, at 02:01, Chris Lattner wrote: > +
  • The C backend does not > support vectors > + yet.
  • > +
  • The C backend does not > support vectors > + yet.
  • Echo, echo… — Gordon -------------- next part -------------- An HTML attachment was scrubbed... URL: From sabre at nondot.org Wed Sep 26 08:48:34 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Sep 2007 15:48:34 -0000 Subject: [llvm-commits] [llvm] r42354 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <200709261548.l8QFmY2g014660@zion.cs.uiuc.edu> Author: lattner Date: Wed Sep 26 10:48:33 2007 New Revision: 42354 URL: http://llvm.org/viewvc/llvm-project?rev=42354&view=rev Log: be less redundantly redundant. Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=42354&r1=42353&r2=42354&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Wed Sep 26 10:48:33 2007 @@ -147,7 +147,7 @@ making the code generator faster for vector code.
  • Evan contributed a new target independent if-converter. While it is - target independent, at this point only the ARM backend uses it so far.
  • + target independent, so far only the ARM backend uses it.
  • Evan rewrite the way the register allocator handles rematerialization, allowing it to be much more effective on two-address targets like X86, From sabre at nondot.org Wed Sep 26 08:50:21 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Sep 2007 15:50:21 -0000 Subject: [llvm-commits] [llvm] r42355 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <200709261550.l8QFoLsw014738@zion.cs.uiuc.edu> Author: lattner Date: Wed Sep 26 10:50:21 2007 New Revision: 42355 URL: http://llvm.org/viewvc/llvm-project?rev=42355&view=rev Log: ok ok we get it. CBE and vectors don't like each other yet. Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=42355&r1=42354&r2=42355&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Wed Sep 26 10:50:21 2007 @@ -484,8 +484,6 @@ assembly code.
  • The C backend does not support vectors yet.
  • -
  • The C backend does not support vectors - yet.
  • The C backend violates the ABI of common C++ programs, preventing intermixing between C++ compiled by the CBE and C++ code compiled with LLC or native compilers.
  • From baldrick at free.fr Wed Sep 26 08:59:54 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 Sep 2007 15:59:54 -0000 Subject: [llvm-commits] [llvm] r42356 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <200709261559.l8QFxshb015013@zion.cs.uiuc.edu> Author: baldrick Date: Wed Sep 26 10:59:54 2007 New Revision: 42356 URL: http://llvm.org/viewvc/llvm-project?rev=42356&view=rev Log: Various cleanups. Especially, EH is turned on by default! Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=42356&r1=42355&r2=42356&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Wed Sep 26 10:59:54 2007 @@ -70,11 +70,11 @@
    -

    LLVM 2.1 brings two new beta C front-ends. First, Duncan, Anton and Devang -has started syncing up llvm-gcc with GCC 4.2, yielding "llvm-gcc 4.2" (creative, -huh?). llvm-gcc 4.2 has the promise to bring much better FORTRAN and Ada -support to LLVM as well as features like atomic builtins, OpenMP, and many other -things. Check it out!

    +

    LLVM 2.1 brings two new beta C front-ends. First, a new version of llvm-gcc +based on GCC 4.2, innovatively called "llvm-gcc-4.2". This promises to bring +FORTRAN and Ada support to LLVM as well as features like atomic builtins and +OpenMP. None of these actually work yet, but don't let that stop you checking +it out!

    Second, LLVM now includes its own native C and Objective-C front-end (C++ is in progress, but is not very far along) code named "

  • Duncan and Anton made significant progress chasing down a number of problems with C++ Zero-Cost exception handling in llvm-gcc 4.0 and 4.2. It is now at - the point where it "just works" on linux/x86-32 and has partial support on + the point where it "just works" on linux/X86-32 and has partial support on other targets.
  • Devang and Duncan fixed a huge number of bugs relating to bitfields, pragma @@ -226,7 +226,7 @@ "restrict" pointer arguments to functions.
  • Duncan contributed support for trampolines (taking the address of a nested - functions), currently this is only supported in the x86 target.
  • + function). Currently this is only supported on the X86 target.
  • Lauro Ramos Venancio contributed support to encode alignment info in load and store instructions, the foundation for other alignment-related @@ -350,7 +350,6 @@
    • The -cee pass is known to be buggy, and may be removed in a future release.
    • -
    • C++ EH support is disabled for this release.
    • The MSIL backend is experimental.
    • The IA64 code generator is experimental.
    • The Alpha backend is experimental.
    • @@ -402,7 +401,7 @@
      • Thumb mode works only on ARMv6 or higher processors. On sub-ARMv6 -processors, thumb program can crash or produces wrong +processors, thumb programs can crash or produce wrong results (PR1388).
      • Compilation for ARM Linux OABI (old ABI) is supported, but not fully tested.
      • @@ -526,9 +525,12 @@
      • llvm-gcc partially supports these GCC extensions:

          -
        1. Nested Functions: As in Algol and Pascal, lexical scoping of functions.
          - Nested functions are supported, but llvm-gcc does not support non-local - gotos or taking the address of a nested function.
        2. +
        3. Nested Functions: + + As in Algol and Pascal, lexical scoping of functions. + Nested functions are supported, but llvm-gcc does not support + taking the address of a nested function (except on the X86 target) + or non-local gotos.
        4. Function Attributes: @@ -620,8 +622,9 @@ itself, Qt, Mozilla, etc.

            -
          • llvm-gcc4 only has partial support for C++ -Exception Handling, and it is not enabled by default.
          • +
          • Exception handling only works well on the linux/x86-32 target. +In some cases, illegally throwing an exception does not result +in a call to terminate.
          • 0) + AI++; + return wrap(AI); +} + +void LLVMGetParams(LLVMValueRef FnRef, LLVMValueRef *ParamRefs) { + Function *Fn = unwrap(FnRef); + for (Function::arg_iterator I = Fn->arg_begin(), + E = Fn->arg_end(); I != E; I++) + *ParamRefs++ = wrap(I); +} + +unsigned LLVMGetIntrinsicID(LLVMValueRef Fn) { + if (Function *F = dyn_cast(unwrap(Fn))) + return F->getIntrinsicID(); + return 0; +} + +unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn) { + return unwrap(Fn)->getCallingConv(); +} + +void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC) { + return unwrap(Fn)->setCallingConv(CC); +} + +/*--.. Operations on basic blocks ..........................................--*/ + +LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef Bb) { + return wrap(static_cast(unwrap(Bb))); +} + +int LLVMValueIsBasicBlock(LLVMValueRef Val) { + return isa(unwrap(Val)); +} + +LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val) { + return wrap(unwrap(Val)); +} + +unsigned LLVMCountBasicBlocks(LLVMValueRef FnRef) { + return unwrap(FnRef)->getBasicBlockList().size(); +} + +void LLVMGetBasicBlocks(LLVMValueRef FnRef, LLVMBasicBlockRef *BasicBlocksRefs){ + Function *Fn = unwrap(FnRef); + for (Function::iterator I = Fn->begin(), E = Fn->end(); I != E; I++) + *BasicBlocksRefs++ = wrap(I); +} + +LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn) { + return wrap(&unwrap(Fn)->getEntryBlock()); +} + +LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef FnRef, const char *Name) { + return wrap(new BasicBlock(Name, unwrap(FnRef))); +} + +LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBBRef, + const char *Name) { + BasicBlock *InsertBeforeBB = unwrap(InsertBeforeBBRef); + return wrap(new BasicBlock(Name, InsertBeforeBB->getParent(), + InsertBeforeBB)); +} + +void LLVMDeleteBasicBlock(LLVMBasicBlockRef BBRef) { + unwrap(BBRef)->eraseFromParent(); +} + +/*--.. Call and invoke instructions ........................................--*/ + +unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr) { + Value *V = unwrap(Instr); + if (CallInst *CI = dyn_cast(V)) + return CI->getCallingConv(); + else if (InvokeInst *II = dyn_cast(V)) + return II->getCallingConv(); + assert(0 && "LLVMGetInstructionCallConv applies only to call and invoke!"); + return 0; +} + +void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC) { + Value *V = unwrap(Instr); + if (CallInst *CI = dyn_cast(V)) + return CI->setCallingConv(CC); + else if (InvokeInst *II = dyn_cast(V)) + return II->setCallingConv(CC); + assert(0 && "LLVMSetInstructionCallConv applies only to call and invoke!"); +} + + +/*===-- Instruction builders ----------------------------------------------===*/ + +LLVMBuilderRef LLVMCreateBuilder() { + return wrap(new LLVMBuilder()); +} + +void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr) { + Instruction *I = unwrap(Instr); + unwrap(Builder)->SetInsertPoint(I->getParent(), I); +} + +void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block) { + BasicBlock *BB = unwrap(Block); + unwrap(Builder)->SetInsertPoint(BB); +} + +void LLVMDisposeBuilder(LLVMBuilderRef Builder) { + delete unwrap(Builder); +} + +/*--.. Instruction builders ................................................--*/ + +LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef B) { + return wrap(unwrap(B)->CreateRetVoid()); +} + +LLVMValueRef LLVMBuildRet(LLVMBuilderRef B, LLVMValueRef V) { + return wrap(unwrap(B)->CreateRet(unwrap(V))); +} + +LLVMValueRef LLVMBuildBr(LLVMBuilderRef B, LLVMBasicBlockRef Dest) { + return wrap(unwrap(B)->CreateBr(unwrap(Dest))); +} + +LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef B, LLVMValueRef If, + LLVMBasicBlockRef Then, LLVMBasicBlockRef Else) { + return wrap(unwrap(B)->CreateCondBr(unwrap(If), unwrap(Then), unwrap(Else))); +} + +LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef B, LLVMValueRef V, + LLVMBasicBlockRef Else, unsigned NumCases) { + return wrap(unwrap(B)->CreateSwitch(unwrap(V), unwrap(Else), NumCases)); +} + +LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, + LLVMValueRef *Args, unsigned NumArgs, + LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, + const char *Name) { + return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch), + unwrap(Args), unwrap(Args) + NumArgs, + Name)); +} + +LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef B) { + return wrap(unwrap(B)->CreateUnwind()); +} + +LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef B) { + return wrap(unwrap(B)->CreateUnreachable()); +} + +/*--.. Arithmetic ..........................................................--*/ + +LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateAdd(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateSub(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateMul(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateUDiv(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildSDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateSDiv(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildFDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFDiv(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildURem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateURem(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildSRem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateSRem(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildFRem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFRem(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildShl(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateShl(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildLShr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateLShr(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildAShr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateAShr(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildAnd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateAnd(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildOr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateOr(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildXor(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateXor(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { + return wrap(unwrap(B)->CreateNeg(unwrap(V), Name)); +} + +LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { + return wrap(unwrap(B)->CreateNot(unwrap(V), Name)); +} + +/*--.. Memory ..............................................................--*/ + +LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, + const char *Name) { + return wrap(unwrap(B)->CreateMalloc(unwrap(Ty), 0, Name)); +} + +LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, + LLVMValueRef Val, const char *Name) { + return wrap(unwrap(B)->CreateMalloc(unwrap(Ty), unwrap(Val), Name)); +} + +LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, + const char *Name) { + return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), 0, Name)); +} + +LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, + LLVMValueRef Val, const char *Name) { + return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), unwrap(Val), Name)); +} + +LLVMValueRef LLVMBuildFree(LLVMBuilderRef B, LLVMValueRef PointerVal) { + return wrap(unwrap(B)->CreateFree(unwrap(PointerVal))); +} + + +LLVMValueRef LLVMBuildLoad(LLVMBuilderRef B, LLVMValueRef PointerVal, + const char *Name) { + return wrap(unwrap(B)->CreateLoad(unwrap(PointerVal), Name)); +} + +LLVMValueRef LLVMBuildStore(LLVMBuilderRef B, LLVMValueRef Val, + LLVMValueRef PointerVal) { + return wrap(unwrap(B)->CreateStore(unwrap(Val), unwrap(PointerVal))); +} + +LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer, + LLVMValueRef *Indices, unsigned NumIndices, + const char *Name) { + return wrap(unwrap(B)->CreateGEP(unwrap(Pointer), unwrap(Indices), + unwrap(Indices) + NumIndices, Name)); +} + +/*--.. Casts ...............................................................--*/ + +LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateTrunc(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildZExt(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateZExt(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildSExt(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateSExt(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildFPToUI(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPToUI(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildFPToSI(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPToSI(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildUIToFP(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateUIToFP(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildSIToFP(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateSIToFP(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildFPTrunc(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPTrunc(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildFPExt(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPExt(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildPtrToInt(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreatePtrToInt(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateIntToPtr(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateBitCast(unwrap(Val), unwrap(DestTy), Name)); +} + +/*--.. Comparisons .........................................................--*/ + +LLVMValueRef LLVMBuildICmp(LLVMBuilderRef B, LLVMIntPredicate Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateICmp(static_cast(Op), + unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef B, LLVMRealPredicate Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFCmp(static_cast(Op), + unwrap(LHS), unwrap(RHS), Name)); +} + +/*--.. Miscellaneous instructions ..........................................--*/ + +LLVMValueRef LLVMBuildPhi(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) { + return wrap(unwrap(B)->CreatePHI(unwrap(Ty), Name)); +} + +LLVMValueRef LLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, + LLVMValueRef *Args, unsigned NumArgs, + const char *Name) { + return wrap(unwrap(B)->CreateCall(unwrap(Fn), unwrap(Args), + unwrap(Args) + NumArgs, Name)); +} + +LLVMValueRef LLVMBuildSelect(LLVMBuilderRef B, LLVMValueRef If, + LLVMValueRef Then, LLVMValueRef Else, + const char *Name) { + return wrap(unwrap(B)->CreateSelect(unwrap(If), unwrap(Then), unwrap(Else), + Name)); +} + +LLVMValueRef LLVMBuildVAArg(LLVMBuilderRef B, LLVMValueRef List, + LLVMTypeRef Ty, const char *Name) { + return wrap(unwrap(B)->CreateVAArg(unwrap(List), unwrap(Ty), Name)); +} + +LLVMValueRef LLVMBuildExtractElement(LLVMBuilderRef B, LLVMValueRef VecVal, + LLVMValueRef Index, const char *Name) { + return wrap(unwrap(B)->CreateExtractElement(unwrap(VecVal), unwrap(Index), + Name)); +} + +LLVMValueRef LLVMBuildInsertElement(LLVMBuilderRef B, LLVMValueRef VecVal, + LLVMValueRef EltVal, LLVMValueRef Index, + const char *Name) { + return wrap(unwrap(B)->CreateInsertElement(unwrap(VecVal), unwrap(EltVal), + unwrap(Index), Name)); +} + +LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef B, LLVMValueRef V1, + LLVMValueRef V2, LLVMValueRef Mask, + const char *Name) { + return wrap(unwrap(B)->CreateShuffleVector(unwrap(V1), unwrap(V2), + unwrap(Mask), Name)); +} Modified: llvm/trunk/test/Bindings/Ocaml/bitwriter.ml URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/Ocaml/bitwriter.ml?rev=42367&r1=42366&r2=42367&view=diff ============================================================================== --- llvm/trunk/test/Bindings/Ocaml/bitwriter.ml (original) +++ llvm/trunk/test/Bindings/Ocaml/bitwriter.ml Wed Sep 26 15:56:12 2007 @@ -11,6 +11,6 @@ let _ = let m = Llvm.create_module "ocaml_test_module" in - ignore (Llvm.add_type_name "caml_int_ty" Llvm.i32_type m); + ignore (Llvm.define_type_name "caml_int_ty" Llvm.i32_type m); test (Llvm_bitwriter.write_bitcode_file m Sys.argv.(1)) Modified: llvm/trunk/test/Bindings/Ocaml/vmcore.ml URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/Ocaml/vmcore.ml?rev=42367&r1=42366&r2=42367&view=diff ============================================================================== --- llvm/trunk/test/Bindings/Ocaml/vmcore.ml (original) +++ llvm/trunk/test/Bindings/Ocaml/vmcore.ml Wed Sep 26 15:56:12 2007 @@ -44,43 +44,43 @@ (* RUN: grep {Ty01.*void} < %t.ll *) group "void"; - insist (add_type_name "Ty01" void_type m); + insist (define_type_name "Ty01" void_type m); insist (Void_type == classify_type void_type); (* RUN: grep {Ty02.*i1} < %t.ll *) group "i1"; - insist (add_type_name "Ty02" i1_type m); + insist (define_type_name "Ty02" i1_type m); insist (Integer_type == classify_type i1_type); (* RUN: grep {Ty03.*i32} < %t.ll *) group "i32"; - insist (add_type_name "Ty03" i32_type m); + insist (define_type_name "Ty03" i32_type m); (* RUN: grep {Ty04.*i42} < %t.ll *) group "i42"; let ty = make_integer_type 42 in - insist (add_type_name "Ty04" ty m); + insist (define_type_name "Ty04" ty m); (* RUN: grep {Ty05.*float} < %t.ll *) group "float"; - insist (add_type_name "Ty05" float_type m); + insist (define_type_name "Ty05" float_type m); insist (Float_type == classify_type float_type); (* RUN: grep {Ty06.*double} < %t.ll *) group "double"; - insist (add_type_name "Ty06" double_type m); + insist (define_type_name "Ty06" double_type m); insist (Double_type == classify_type double_type); (* RUN: grep {Ty07.*i32.*i1, double} < %t.ll *) group "function"; let ty = make_function_type i32_type [| i1_type; double_type |] false in - insist (add_type_name "Ty07" ty m); + insist (define_type_name "Ty07" ty m); insist (Function_type = classify_type ty); insist (not (is_var_arg ty)); insist (i32_type == return_type ty); @@ -90,14 +90,14 @@ *) group "vararg"; let ty = make_function_type void_type [| i32_type |] true in - insist (add_type_name "Ty08" ty m); + insist (define_type_name "Ty08" ty m); insist (is_var_arg ty); (* RUN: grep {Ty09.*\\\[7 x i8\\\]} < %t.ll *) group "array"; let ty = make_array_type i8_type 7 in - insist (add_type_name "Ty09" ty m); + insist (define_type_name "Ty09" ty m); insist (7 = array_length ty); insist (i8_type == element_type ty); insist (Array_type == classify_type ty); @@ -106,7 +106,7 @@ *) group "pointer"; let ty = make_pointer_type float_type in - insist (add_type_name "Ty10" ty m); + insist (define_type_name "Ty10" ty m); insist (float_type == element_type ty); insist (Pointer_type == classify_type ty); @@ -114,7 +114,7 @@ *) group "vector"; let ty = make_vector_type i16_type 4 in - insist (add_type_name "Ty11" ty m); + insist (define_type_name "Ty11" ty m); insist (i16_type == element_type ty); insist (4 = vector_size ty); @@ -122,9 +122,16 @@ *) group "opaque"; let ty = make_opaque_type () in - insist (add_type_name "Ty12" ty m); + insist (define_type_name "Ty12" ty m); insist (ty == ty); - insist (ty <> make_opaque_type ()) + insist (ty <> make_opaque_type ()); + + (* RUN: grep -v {Ty13} < %t.ll + *) + group "delete"; + let ty = make_opaque_type () in + insist (define_type_name "Ty13" ty m); + delete_type_name "Ty13" m (*===-- Constants ---------------------------------------------------------===*) @@ -163,9 +170,6 @@ *) group "string w/ null"; let c = make_string_constant "hi\000again" true in - prerr_string "====> "; - prerr_int (array_length (type_of c)); - prerr_endline " <===="; ignore (define_global "Const05" c m); insist ((make_array_type i8_type 9) = type_of c); @@ -306,6 +310,317 @@ delete_global g +(*===-- Functions ---------------------------------------------------------===*) + +let test_functions () = + let ty = make_function_type i32_type [| i32_type; i64_type |] false in + let pty = make_pointer_type ty in + + (* RUN: grep {declare i32 @Fn1\(i32, i64\)} < %t.ll + *) + group "declare"; + let fn = declare_function "Fn1" ty m in + insist (pty = type_of fn); + insist (is_declaration fn); + insist (0 = Array.length (basic_blocks fn)); + + (* RUN: grep -v {Fn2} < %t.ll + *) + group "delete"; + let fn = declare_function "Fn2" ty m in + delete_function fn; + + (* RUN: grep {define.*Fn3} < %t.ll + *) + group "define"; + 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 *) + + (* RUN: grep {define.*Fn4.*Param1.*Param2} < %t.ll + *) + group "params"; + let fn = define_function "Fn4" ty m in + let params = params fn in + insist (2 = Array.length params); + insist (params.(0) = param fn 0); + insist (params.(1) = param fn 1); + insist (i32_type = type_of params.(0)); + 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 *) + + (* RUN: grep {fastcc.*Fn5} < %t.ll + *) + group "callconv"; + 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) + + +(*===-- Basic Blocks ------------------------------------------------------===*) + +let test_basic_blocks () = + let ty = make_function_type void_type [| |] false in + + (* RUN: grep {Bb1} < %t.ll + *) + group "entry"; + let fn = declare_function "X" ty m in + let bb = append_block "Bb1" fn in + insist (bb = entry_block fn); + + (* RUN: grep -v Bb2 < %t.ll + *) + group "delete"; + let fn = declare_function "X2" ty m in + let bb = append_block "Bb2" fn in + delete_block bb; + + group "insert"; + let fn = declare_function "X3" ty m in + let bbb = append_block "" fn in + let bba = insert_block "" bbb in + insist ([| bba; bbb |] = basic_blocks fn); + + (* RUN: grep Bb3 < %t.ll + *) + group "name/value"; + let fn = define_function "X4" ty m in + let bb = entry_block fn in + let bbv = value_of_block bb in + set_value_name "Bb3" bbv; + insist ("Bb3" = value_name bbv); + + group "casts"; + let fn = define_function "X5" ty m in + let bb = entry_block fn in + insist (bb = block_of_value (value_of_block bb)); + insist (value_is_block (value_of_block bb)); + insist (not (value_is_block (make_null i32_type))) + + +(*===-- Builder -----------------------------------------------------------===*) + +let test_builder () = + let (++) x f = f x; x in + + group "ret void"; + begin + (* RUN: grep {ret void} < %t.ll + *) + let fty = make_function_type void_type [| |] false in + let fn = declare_function "X6" fty m in + let b = builder_at_end (append_block "Bb01" fn) in + ignore (build_ret_void b) + end; + + (* The rest of the tests will use one big function. *) + let fty = make_function_type i32_type [| i32_type; i32_type |] false in + let fn = define_function "X7" fty m in + let atentry = builder_at_end (entry_block fn) in + let p1 = param fn 0 ++ set_value_name "P1" in + let p2 = param fn 1 ++ set_value_name "P2" in + let f1 = build_uitofp p1 float_type "F1" atentry in + let f2 = build_uitofp p2 float_type "F2" atentry in + + let bb00 = append_block "Bb00" fn in + ignore (build_unreachable (builder_at_end bb00)); + + group "ret"; begin + (* RUN: grep {ret.*P1} < %t.ll + *) + let ret = build_ret p1 atentry in + position_before ret atentry + end; + + group "br"; begin + (* RUN: grep {br.*Bb02} < %t.ll + *) + let bb02 = append_block "Bb02" fn in + let b = builder_at_end bb02 in + ignore (build_br bb02 b) + end; + + group "cond_br"; begin + (* RUN: grep {br.*Inst01.*Bb03.*Bb00} < %t.ll + *) + let bb03 = append_block "Bb03" fn in + let b = builder_at_end bb03 in + let cond = build_trunc p1 i1_type "Inst01" b in + ignore (build_cond_br cond bb03 bb00 b) + end; + + (* TODO: Switch *) + + group "invoke"; begin + (* RUN: grep {Inst02.*invoke.*P1.*P2} < %t.ll + * RUN: grep {to.*Bb04.*unwind.*Bb00} < %t.ll + *) + let bb04 = append_block "Bb04" fn in + let b = builder_at_end bb04 in + ignore (build_invoke fn [| p1; p2 |] bb04 bb00 "Inst02" b) + end; + + group "unwind"; begin + (* RUN: grep {unwind} < %t.ll + *) + let bb05 = append_block "Bb05" fn in + let b = builder_at_end bb05 in + ignore (build_unwind b) + end; + + group "unreachable"; begin + (* RUN: grep {unreachable} < %t.ll + *) + let bb06 = append_block "Bb06" fn in + let b = builder_at_end bb06 in + ignore (build_unreachable b) + end; + + group "arithmetic"; begin + let bb07 = append_block "Bb07" fn in + let b = builder_at_end bb07 in + + (* RUN: grep {Inst03.*add.*P1.*P2} < %t.ll + * RUN: grep {Inst04.*sub.*P1.*Inst03} < %t.ll + * RUN: grep {Inst05.*mul.*P1.*Inst04} < %t.ll + * RUN: grep {Inst06.*udiv.*P1.*Inst05} < %t.ll + * RUN: grep {Inst07.*sdiv.*P1.*Inst06} < %t.ll + * RUN: grep {Inst08.*fdiv.*F1.*F2} < %t.ll + * RUN: grep {Inst09.*urem.*P1.*Inst07} < %t.ll + * RUN: grep {Inst10.*srem.*P1.*Inst09} < %t.ll + * RUN: grep {Inst11.*frem.*F1.*Inst08} < %t.ll + * RUN: grep {Inst12.*shl.*P1.*Inst10} < %t.ll + * RUN: grep {Inst13.*lshr.*P1.*Inst12} < %t.ll + * RUN: grep {Inst14.*ashr.*P1.*Inst13} < %t.ll + * RUN: grep {Inst15.*and.*P1.*Inst14} < %t.ll + * RUN: grep {Inst16.*or.*P1.*Inst15} < %t.ll + * RUN: grep {Inst17.*xor.*P1.*Inst16} < %t.ll + * RUN: grep {Inst18.*sub.*0.*Inst17} < %t.ll + * RUN: grep {Inst19.*xor.*Inst18.*-1} < %t.ll + *) + let inst03 = build_add p1 p2 "Inst03" b in + let inst04 = build_sub p1 inst03 "Inst04" b in + let inst05 = build_mul p1 inst04 "Inst05" b in + let inst06 = build_udiv p1 inst05 "Inst06" b in + let inst07 = build_sdiv p1 inst06 "Inst07" b in + let inst08 = build_fdiv f1 f2 "Inst08" b in + let inst09 = build_urem p1 inst07 "Inst09" b in + let inst10 = build_srem p1 inst09 "Inst10" b in + ignore(build_frem f1 inst08 "Inst11" b); + let inst12 = build_shl p1 inst10 "Inst12" b in + let inst13 = build_lshr p1 inst12 "Inst13" b in + let inst14 = build_ashr p1 inst13 "Inst14" b in + let inst15 = build_and p1 inst14 "Inst15" b in + 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) + end; + + group "memory"; begin + let bb08 = append_block "Bb08" fn in + let b = builder_at_end bb08 in + + (* RUN: grep {Inst20.*malloc.*i8 } < %t.ll + * RUN: grep {Inst21.*malloc.*i8.*P1} < %t.ll + * RUN: grep {Inst22.*alloca.*i32 } < %t.ll + * RUN: grep {Inst23.*alloca.*i32.*P2} < %t.ll + * RUN: grep {free.*Inst20} < %t.ll + * RUN: grep {Inst25.*load.*Inst21} < %t.ll + * RUN: grep {store.*P2.*Inst22} < %t.ll + * RUN: grep {Inst27.*getelementptr.*Inst23.*P2} < %t.ll + *) + let inst20 = build_malloc i8_type "Inst20" b in + let inst21 = build_array_malloc i8_type p1 "Inst21" b in + let inst22 = build_alloca i32_type "Inst22" b in + let inst23 = build_array_alloca i32_type p2 "Inst23" b in + ignore(build_free inst20 b); + ignore(build_load inst21 "Inst25" b); + ignore(build_store p2 inst22 b); + ignore(build_gep inst23 [| p2 |] "Inst27" b) + end; + + group "casts"; begin + let void_ptr = make_pointer_type i8_type in + + (* RUN: grep {Inst28.*trunc.*P1.*i8} < %t.ll + * RUN: grep {Inst29.*zext.*Inst28.*i32} < %t.ll + * RUN: grep {Inst30.*sext.*Inst29.*i64} < %t.ll + * RUN: grep {Inst31.*uitofp.*Inst30.*float} < %t.ll + * RUN: grep {Inst32.*sitofp.*Inst29.*double} < %t.ll + * RUN: grep {Inst33.*fptoui.*Inst31.*i32} < %t.ll + * RUN: grep {Inst34.*fptosi.*Inst32.*i64} < %t.ll + * RUN: grep {Inst35.*fptrunc.*Inst32.*float} < %t.ll + * RUN: grep {Inst36.*fpext.*Inst35.*double} < %t.ll + * RUN: grep {Inst37.*inttoptr.*P1.*i8\*} < %t.ll + * RUN: grep {Inst38.*ptrtoint.*Inst37.*i64} < %t.ll + * RUN: grep {Inst39.*bitcast.*Inst38.*double} < %t.ll + *) + let inst28 = build_trunc p1 i8_type "Inst28" atentry in + let inst29 = build_zext inst28 i32_type "Inst29" atentry in + let inst30 = build_sext inst29 i64_type "Inst30" atentry in + let inst31 = build_uitofp inst30 float_type "Inst31" atentry in + let inst32 = build_sitofp inst29 double_type "Inst32" atentry in + ignore(build_fptoui inst31 i32_type "Inst33" atentry); + ignore(build_fptosi inst32 i64_type "Inst34" atentry); + let inst35 = build_fptrunc inst32 float_type "Inst35" atentry in + ignore(build_fpext inst35 double_type "Inst36" atentry); + let inst37 = build_inttoptr p1 void_ptr "Inst37" atentry in + let inst38 = build_ptrtoint inst37 i64_type "Inst38" atentry in + ignore(build_bitcast inst38 double_type "Inst39" atentry) + end; + + group "comparisons"; begin + (* RUN: grep {Inst40.*icmp.*ne.*P1.*P2} < %t.ll + * RUN: grep {Inst41.*icmp.*sle.*P2.*P1} < %t.ll + * RUN: grep {Inst42.*fcmp.*false.*F1.*F2} < %t.ll + * RUN: grep {Inst43.*fcmp.*true.*F2.*F1} < %t.ll + *) + ignore (build_icmp Icmp_ne p1 p2 "Inst40" atentry); + ignore (build_icmp Icmp_sle p2 p1 "Inst41" atentry); + ignore (build_fcmp Fcmp_false f1 f2 "Inst42" atentry); + ignore (build_fcmp Fcmp_true f2 f1 "Inst43" atentry) + end; + + group "miscellaneous"; begin + (* RUN: grep {Inst45.*call.*P2.*P1} < %t.ll + * RUN: grep {Inst47.*select.*Inst46.*P1.*P2} < %t.ll + * 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 + *) + + (* 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); + ignore (build_va_arg + (make_null (make_pointer_type (make_pointer_type i8_type))) + i32_type "Inst48" atentry); + + (* Set up some vector vregs. *) + let one = make_int_constant i32_type (-1) true in + let zero = make_int_constant i32_type 1 true in + let t1 = make_vector_constant [| one; zero; one; zero |] in + let t2 = make_vector_constant [| zero; one; zero; one |] in + let t3 = make_vector_constant [| one; one; zero; zero |] in + let vec1 = build_insertelement t1 p1 p2 "Vec1" atentry in + let vec2 = build_insertelement t2 p1 p2 "Vec2" atentry in + let vec3 = build_insertelement t3 p1 p2 "Vec3" atentry in + + ignore (build_extractelement vec1 p2 "Inst49" atentry); + ignore (build_insertelement vec1 p1 p2 "Inst50" atentry); + ignore (build_shufflevector vec1 vec2 vec3 "Inst51" atentry); + end + + (*===-- Writer ------------------------------------------------------------===*) let test_writer () = @@ -322,5 +637,8 @@ suite "constants" test_constants; suite "global values" test_global_values; suite "global variables" test_global_variables; + suite "functions" test_functions; + suite "basic blocks" test_basic_blocks; + suite "builder" test_builder; suite "writer" test_writer; exit !exit_status From dalej at apple.com Wed Sep 26 14:10:55 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 26 Sep 2007 21:10:55 -0000 Subject: [llvm-commits] [llvm] r42368 - in /llvm/trunk/lib: CodeGen/SelectionDAG/SelectionDAGISel.cpp Target/X86/X86ISelLowering.cpp Message-ID: <200709262110.l8QLAtPL025176@zion.cs.uiuc.edu> Author: johannes Date: Wed Sep 26 16:10:55 2007 New Revision: 42368 URL: http://llvm.org/viewvc/llvm-project?rev=42368&view=rev Log: Enable codegen for long double abs, sin, cos Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=42368&r1=42367&r2=42368&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Sep 26 16:10:55 2007 @@ -2996,7 +2996,8 @@ } } else if (NameStr[0] == 'f' && ((NameLen == 4 && !strcmp(NameStr, "fabs")) || - (NameLen == 5 && !strcmp(NameStr, "fabsf")))) { + (NameLen == 5 && !strcmp(NameStr, "fabsf")) || + (NameLen == 5 && !strcmp(NameStr, "fabsl")))) { if (I.getNumOperands() == 2 && // Basic sanity checks. I.getOperand(1)->getType()->isFloatingPoint() && I.getType() == I.getOperand(1)->getType()) { @@ -3006,7 +3007,8 @@ } } else if (NameStr[0] == 's' && ((NameLen == 3 && !strcmp(NameStr, "sin")) || - (NameLen == 4 && !strcmp(NameStr, "sinf")))) { + (NameLen == 4 && !strcmp(NameStr, "sinf")) || + (NameLen == 4 && !strcmp(NameStr, "sinl")))) { if (I.getNumOperands() == 2 && // Basic sanity checks. I.getOperand(1)->getType()->isFloatingPoint() && I.getType() == I.getOperand(1)->getType()) { @@ -3016,7 +3018,8 @@ } } else if (NameStr[0] == 'c' && ((NameLen == 3 && !strcmp(NameStr, "cos")) || - (NameLen == 4 && !strcmp(NameStr, "cosf")))) { + (NameLen == 4 && !strcmp(NameStr, "cosf")) || + (NameLen == 4 && !strcmp(NameStr, "cosl")))) { if (I.getNumOperands() == 2 && // Basic sanity checks. I.getOperand(1)->getType()->isFloatingPoint() && I.getType() == I.getOperand(1)->getType()) { Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=42368&r1=42367&r2=42368&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Sep 26 16:10:55 2007 @@ -418,6 +418,10 @@ setOperationAction(ISD::UNDEF, MVT::f80, Expand); setOperationAction(ISD::FCOPYSIGN, MVT::f80, Expand); setOperationAction(ISD::ConstantFP, MVT::f80, Expand); + if (!UnsafeFPMath) { + setOperationAction(ISD::FSIN , MVT::f80 , Expand); + setOperationAction(ISD::FCOS , 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. From dalej at apple.com Wed Sep 26 14:12:11 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 26 Sep 2007 21:12:11 -0000 Subject: [llvm-commits] [llvm] r42369 - in /llvm/trunk/test/CodeGen/X86: fabs.ll sincos.ll Message-ID: <200709262112.l8QLCB32025264@zion.cs.uiuc.edu> Author: johannes Date: Wed Sep 26 16:12:10 2007 New Revision: 42369 URL: http://llvm.org/viewvc/llvm-project?rev=42369&view=rev Log: Modernize fabs.ll, add long double. Add tests for direct codegen of fsin/fcos. Added: llvm/trunk/test/CodeGen/X86/sincos.ll Modified: llvm/trunk/test/CodeGen/X86/fabs.ll Modified: llvm/trunk/test/CodeGen/X86/fabs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fabs.ll?rev=42369&r1=42368&r2=42369&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/fabs.ll (original) +++ llvm/trunk/test/CodeGen/X86/fabs.ll Wed Sep 26 16:12:10 2007 @@ -1,24 +1,29 @@ ; Make sure this testcase codegens to the fabs instruction, not a call to fabsf -; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86 -mattr=-sse2,-sse3,-sse | \ -; RUN: grep fabs\$ | count 1 -; RUN: llvm-upgrade < %s | llvm-as | \ -; RUN: llc -march=x86 -mattr=-sse,-sse2,-sse3 -enable-unsafe-fp-math | \ -; RUN: grep fabs\$ | count 2 +; RUN: llvm-as < %s | llc -march=x86 -mattr=-sse2,-sse3,-sse | grep fabs\$ | \ +; RUN: count 2 +; RUN: llvm-as < %s | \ +; RUN: llc -march=x86 -mattr=-sse,-sse2,-sse3 -enable-unsafe-fp-math | \ +; RUN: grep fabs\$ | count 3 -target endian = little -target pointersize = 32 +declare float @fabsf(float) -declare float %fabsf(float) +declare x86_fp80 @fabsl(x86_fp80) -float %test1(float %X) { - %Y = call float %fabsf(float %X) +define float @test1(float %X) { + %Y = call float @fabsf(float %X) ret float %Y } -double %test2(double %X) { - %Y = setge double %X, -0.0 +define double @test2(double %X) { + %Y = fcmp oge double %X, -0.0 %Z = sub double -0.0, %X - %Q = select bool %Y, double %X, double %Z + %Q = select i1 %Y, double %X, double %Z ret double %Q } +define x86_fp80 @test3(x86_fp80 %X) { + %Y = call x86_fp80 @fabsl(x86_fp80 %X) + ret x86_fp80 %Y +} + + Added: llvm/trunk/test/CodeGen/X86/sincos.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sincos.ll?rev=42369&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/sincos.ll (added) +++ llvm/trunk/test/CodeGen/X86/sincos.ll Wed Sep 26 16:12:10 2007 @@ -0,0 +1,50 @@ +; Make sure this testcase codegens to the sin and cos instructions, not calls +; RUN: llvm-as < %s | \ +; RUN: llc -march=x86 -mattr=-sse,-sse2,-sse3 -enable-unsafe-fp-math | \ +; RUN: grep sin\$ | count 3 +; RUN: llvm-as < %s | \ +; RUN: llc -march=x86 -mattr=-sse,-sse2,-sse3 -enable-unsafe-fp-math | \ +; RUN: grep cos\$ | count 3 + +declare float @sinf(float) + +declare double @sin(double) + +declare x86_fp80 @sinl(x86_fp80) + +define float @test1(float %X) { + %Y = call float @sinf(float %X) + ret float %Y +} + +define double @test2(double %X) { + %Y = call double @sin(double %X) + ret double %Y +} + +define x86_fp80 @test3(x86_fp80 %X) { + %Y = call x86_fp80 @sinl(x86_fp80 %X) + ret x86_fp80 %Y +} + +declare float @cosf(float) + +declare double @cos(double) + +declare x86_fp80 @cosl(x86_fp80) + +define float @test4(float %X) { + %Y = call float @cosf(float %X) + ret float %Y +} + +define double @test5(double %X) { + %Y = call double @cos(double %X) + ret double %Y +} + +define x86_fp80 @test6(x86_fp80 %X) { + %Y = call x86_fp80 @cosl(x86_fp80 %X) + ret x86_fp80 %Y +} + From evan.cheng at apple.com Wed Sep 26 14:28:00 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Sep 2007 21:28:00 -0000 Subject: [llvm-commits] [llvm] r42371 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.td X86InstrX86-64.td Message-ID: <200709262128.l8QLS1is026229@zion.cs.uiuc.edu> Author: evancheng Date: Wed Sep 26 16:28:00 2007 New Revision: 42371 URL: http://llvm.org/viewvc/llvm-project?rev=42371&view=rev Log: Some assemblers do not recognize aliases pushfd, pushfq, popfd, and popfq. Just emit them as pushf and popf. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td llvm/trunk/lib/Target/X86/X86InstrX86-64.td Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=42371&r1=42370&r2=42371&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed Sep 26 16:28:00 2007 @@ -430,9 +430,9 @@ } let Defs = [ESP, EFLAGS], Uses = [ESP] in -def POPFD : I<0x9D, RawFrm, (outs), (ins), "popfd", []>; +def POPFD : I<0x9D, RawFrm, (outs), (ins), "popf", []>; let Defs = [ESP], Uses = [ESP, EFLAGS] in -def PUSHFD : I<0x9C, RawFrm, (outs), (ins), "pushfd", []>; +def PUSHFD : I<0x9C, RawFrm, (outs), (ins), "pushf", []>; def MovePCtoStack : I<0, Pseudo, (outs), (ins piclabel:$label), "call\t$label", []>; 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=42371&r1=42370&r2=42371&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrX86-64.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrX86-64.td Wed Sep 26 16:28:00 2007 @@ -124,9 +124,9 @@ } let Defs = [RSP, EFLAGS], Uses = [RSP] in -def POPFQ : I<0x9D, RawFrm, (outs), (ins), "popfq", []>, REX_W; +def POPFQ : I<0x9D, RawFrm, (outs), (ins), "popf", []>, REX_W; let Defs = [RSP], Uses = [RSP, EFLAGS] in -def PUSHFQ : I<0x9C, RawFrm, (outs), (ins), "pushfq", []>; +def PUSHFQ : I<0x9C, RawFrm, (outs), (ins), "pushf", []>; def LEA64_32r : I<0x8D, MRMSrcMem, (outs GR32:$dst), (ins lea64_32mem:$src), From dpatel at apple.com Wed Sep 26 14:30:19 2007 From: dpatel at apple.com (Devang Patel) Date: Wed, 26 Sep 2007 14:30:19 -0700 Subject: [llvm-commits] [llvm-gcc-4.0] r42353 - in /llvm-gcc-4.0/trunk/gcc: config/alpha/unicosmk.h config/darwin.h objc/objc-act.c In-Reply-To: <200709260906.l8Q960Pr001546@zion.cs.uiuc.edu> References: <200709260906.l8Q960Pr001546@zion.cs.uiuc.edu> Message-ID: <4B72D5FA-1E0D-4A58-949F-51C00F58406E@apple.com> On Sep 26, 2007, at 2:06 AM, Anton Korobeynikov wrote: > Author: asl > Date: Wed Sep 26 04:05:59 2007 > New Revision: 42353 > > URL: http://llvm.org/viewvc/llvm-project?rev=42353&view=rev > Log: > Unbreak objc on non-darwin This breaks bootstrap on darwin. cc1: warnings being treated as errors /Volumes/src/clean/llvm-gcc.roots/llvm-gcc~obj/src/gcc/objc/objc- act.c: In function ‘objc_init_exceptions’: /Volumes/src/clean/llvm-gcc.roots/llvm-gcc~obj/src/gcc/objc/objc-act.c: 7649: warning: null argument where non-null required (argument 1) /Volumes/src/clean/llvm-gcc.roots/llvm-gcc~obj/src/gcc/objc/objc-act.c: 7649: warning: too many arguments for format - Devang From evan.cheng at apple.com Wed Sep 26 14:31:07 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Sep 2007 21:31:07 -0000 Subject: [llvm-commits] [llvm] r42372 - in /llvm/trunk: include/llvm/Target/MRegisterInfo.h lib/Target/X86/X86RegisterInfo.cpp lib/Target/X86/X86RegisterInfo.h Message-ID: <200709262131.l8QLV7Kq026397@zion.cs.uiuc.edu> Author: evancheng Date: Wed Sep 26 16:31:07 2007 New Revision: 42372 URL: http://llvm.org/viewvc/llvm-project?rev=42372&view=rev Log: - Added MRegisterInfo::getCrossCopyRegClass() hook. For register classes where reg to reg copies are not possible, this returns another register class which registers in the specified register class can be copied to (and copy back from). - X86 copyRegToReg() now supports copying between EFLAGS and GR32 / GR64 registers. 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=42372&r1=42371&r2=42372&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/MRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/MRegisterInfo.h Wed Sep 26 16:31:07 2007 @@ -315,6 +315,11 @@ return Reg >= FirstVirtualRegister; } + /// getPhysicalRegisterRegClass - Returns the Register Class of a physical + /// register of the given type. + const TargetRegisterClass *getPhysicalRegisterRegClass(MVT::ValueType VT, + unsigned Reg) const; + /// getAllocatableSet - Returns a bitset indexed by register number /// indicating if a register is allocatable or not. If a register class is /// specified, returns the subset for the class. @@ -509,6 +514,14 @@ const TargetRegisterClass *DestRC, const TargetRegisterClass *SrcRC) const = 0; + /// getCrossCopyRegClass - Returns a legal register class to copy a register + /// in the specified class to or from. Returns NULL if it is possible to copy + /// between a two registers of the specified class. + virtual const TargetRegisterClass * + getCrossCopyRegClass(const TargetRegisterClass *RC) const { + return NULL; + } + /// reMaterialize - Re-issue the specified 'original' instruction at the /// specific location targeting a new destination register. virtual void reMaterialize(MachineBasicBlock &MBB, Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=42372&r1=42371&r2=42372&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Wed Sep 26 16:31:07 2007 @@ -234,6 +234,30 @@ const TargetRegisterClass *DestRC, const TargetRegisterClass *SrcRC) const { if (DestRC != SrcRC) { + // Moving EFLAGS to / from another register requires a push and a pop. + if (SrcRC == &X86::CCRRegClass) { + assert(SrcReg == X86::EFLAGS); + if (DestRC == &X86::GR64RegClass) { + BuildMI(MBB, MI, TII.get(X86::PUSHFQ)); + BuildMI(MBB, MI, TII.get(X86::POP64r), DestReg); + return; + } else if (DestRC == &X86::GR32RegClass) { + BuildMI(MBB, MI, TII.get(X86::PUSHFD)); + BuildMI(MBB, MI, TII.get(X86::POP32r), DestReg); + return; + } + } else if (DestRC == &X86::CCRRegClass) { + assert(DestReg == X86::EFLAGS); + if (SrcRC == &X86::GR64RegClass) { + BuildMI(MBB, MI, TII.get(X86::PUSH64r)).addReg(SrcReg); + BuildMI(MBB, MI, TII.get(X86::POPFQ)); + return; + } else if (SrcRC == &X86::GR32RegClass) { + BuildMI(MBB, MI, TII.get(X86::PUSH32r)).addReg(SrcReg); + BuildMI(MBB, MI, TII.get(X86::POPFD)); + return; + } + } cerr << "Not yet supported!"; abort(); } @@ -272,6 +296,12 @@ BuildMI(MBB, MI, TII.get(Opc), DestReg).addReg(SrcReg); } +const TargetRegisterClass * +X86RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { + if (RC == &X86::CCRRegClass) + return &X86::GR32RegClass; + return NULL; +} void X86RegisterInfo::reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.h?rev=42372&r1=42371&r2=42372&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.h Wed Sep 26 16:31:07 2007 @@ -81,6 +81,9 @@ const TargetRegisterClass *DestRC, const TargetRegisterClass *SrcRC) const; + const TargetRegisterClass * + getCrossCopyRegClass(const TargetRegisterClass *RC) const; + void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, const MachineInstr *Orig) const; From neil at daikokuya.co.uk Wed Sep 26 14:33:42 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Wed, 26 Sep 2007 21:33:42 -0000 Subject: [llvm-commits] [llvm] r42373 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200709262133.l8QLXgdx026535@zion.cs.uiuc.edu> Author: neil Date: Wed Sep 26 16:33:42 2007 New Revision: 42373 URL: http://llvm.org/viewvc/llvm-project?rev=42373&view=rev Log: Whitespace and compiler warning cleanup. 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=42373&r1=42372&r2=42373&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Wed Sep 26 16:33:42 2007 @@ -113,12 +113,12 @@ value = digitValue(*p); if(value == -1U) - break; + break; p++; unsignedExponent = unsignedExponent * 10 + value; if(unsignedExponent > 65535) - overflow = true; + overflow = true; } if(exponentAdjustment > 65535 || exponentAdjustment < -65536) @@ -127,10 +127,10 @@ if(!overflow) { exponent = unsignedExponent; if(negative) - exponent = -exponent; + exponent = -exponent; exponent += exponentAdjustment; if(exponent > 65535 || exponent < -65536) - overflow = true; + overflow = true; } if(overflow) @@ -149,7 +149,7 @@ if(*p == '.') { *dot = p++; while(*p == '0') - p++; + p++; } return p; @@ -187,8 +187,8 @@ /* Return the fraction lost were a bignum truncated. */ lostFraction lostFractionThroughTruncation(integerPart *parts, - unsigned int partCount, - unsigned int bits) + unsigned int partCount, + unsigned int bits) { unsigned int lsb; @@ -258,7 +258,7 @@ assert(rhs.partCount() >= partCount()); APInt::tcAssign(significandParts(), rhs.significandParts(), - partCount()); + partCount()); } APFloat & @@ -310,7 +310,7 @@ } APFloat::APFloat(const fltSemantics &ourSemantics, - fltCategory ourCategory, bool negative) + fltCategory ourCategory, bool negative) { initialize(&ourSemantics); category = ourCategory; @@ -368,7 +368,7 @@ /* Combine the effect of two lost fractions. */ lostFraction APFloat::combineLostFractions(lostFraction moreSignificant, - lostFraction lessSignificant) + lostFraction lessSignificant) { if(lessSignificant != lfExactlyZero) { if(moreSignificant == lfExactlyZero) @@ -426,7 +426,7 @@ assert(exponent == rhs.exponent); return APInt::tcSubtract(parts, rhs.significandParts(), borrow, - partCount()); + partCount()); } /* Multiply the significand of the RHS. If ADDEND is non-NULL, add it @@ -435,7 +435,7 @@ lostFraction APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) { - unsigned int omsb; // One, not zero, based MSB. + unsigned int omsb; // One, not zero, based MSB. unsigned int partsCount, newPartsCount, precision; integerPart *lhsSignificand; integerPart scratch[4]; @@ -456,7 +456,7 @@ partsCount = partCount(); APInt::tcFullMultiply(fullSignificand, lhsSignificand, - rhs.significandParts(), partsCount); + rhs.significandParts(), partsCount); lost_fraction = lfExactlyZero; omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1; @@ -473,9 +473,9 @@ extendedPrecision = precision + precision - 1; if(omsb != extendedPrecision) { - APInt::tcShiftLeft(fullSignificand, newPartsCount, - extendedPrecision - omsb); - exponent -= extendedPrecision - omsb; + APInt::tcShiftLeft(fullSignificand, newPartsCount, + extendedPrecision - omsb); + exponent -= extendedPrecision - omsb; } /* Create new semantics. */ @@ -660,7 +660,7 @@ significands. */ if(compare == 0) compare = APInt::tcCompare(significandParts(), rhs.significandParts(), - partCount()); + partCount()); if(compare > 0) return cmpGreaterThan; @@ -689,7 +689,7 @@ category = fcNormal; exponent = semantics->maxExponent; APInt::tcSetLeastSignificantBits(significandParts(), partCount(), - semantics->precision); + semantics->precision); return opInexact; } @@ -698,7 +698,7 @@ numbers. */ bool APFloat::roundAwayFromZero(roundingMode rounding_mode, - lostFraction lost_fraction) + lostFraction lost_fraction) { /* NaNs and infinities should not have lost fractions. */ assert(category == fcNormal || category == fcZero); @@ -736,9 +736,9 @@ APFloat::opStatus APFloat::normalize(roundingMode rounding_mode, - lostFraction lost_fraction) + lostFraction lost_fraction) { - unsigned int omsb; /* One, not zero, based MSB. */ + unsigned int omsb; /* One, not zero, based MSB. */ int exponentChange; if(category != fcNormal) @@ -782,9 +782,9 @@ /* Keep OMSB up-to-date. */ if(omsb > (unsigned) exponentChange) - omsb -= (unsigned) exponentChange; + omsb -= (unsigned) exponentChange; else - omsb = 0; + omsb = 0; } } @@ -812,12 +812,12 @@ /* Did the significand increment overflow? */ if(omsb == (unsigned) semantics->precision + 1) { /* Renormalize by incrementing the exponent and shifting our - significand right one. However if we already have the - maximum exponent we overflow to infinity. */ + significand right one. However if we already have the + maximum exponent we overflow to infinity. */ if(exponent == semantics->maxExponent) { - category = fcInfinity; + category = fcInfinity; - return (opStatus) (opOverflow | opInexact); + return (opStatus) (opOverflow | opInexact); } shiftSignificandRight(1); @@ -933,12 +933,12 @@ if (reverse) { carry = temp_rhs.subtractSignificand - (*this, lost_fraction != lfExactlyZero); + (*this, lost_fraction != lfExactlyZero); copySignificand(temp_rhs); sign = !sign; } else { carry = subtractSignificand - (temp_rhs, lost_fraction != lfExactlyZero); + (temp_rhs, lost_fraction != lfExactlyZero); } /* Invert the lost fraction - it was on the RHS and @@ -1082,7 +1082,7 @@ /* Normalized addition or subtraction. */ APFloat::opStatus APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode, - bool subtract) + bool subtract) { opStatus fs; @@ -1175,12 +1175,12 @@ int parts = partCount(); integerPart *x = new integerPart[parts]; - fs = V.convertToInteger(x, parts * integerPartWidth, true, + fs = V.convertToInteger(x, parts * integerPartWidth, true, rmNearestTiesToEven); if (fs==opInvalidOp) return fs; - fs = V.convertFromInteger(x, parts * integerPartWidth, true, + fs = V.convertFromInteger(x, parts * integerPartWidth, true, rmNearestTiesToEven); assert(fs==opOK); // should always work @@ -1199,8 +1199,8 @@ /* Normalized fused-multiply-add. */ APFloat::opStatus APFloat::fusedMultiplyAdd(const APFloat &multiplicand, - const APFloat &addend, - roundingMode rounding_mode) + const APFloat &addend, + roundingMode rounding_mode) { opStatus fs; @@ -1305,9 +1305,9 @@ if(sign) { if(result == cmpLessThan) - result = cmpGreaterThan; + result = cmpGreaterThan; else if(result == cmpGreaterThan) - result = cmpLessThan; + result = cmpLessThan; } } @@ -1316,12 +1316,12 @@ APFloat::opStatus APFloat::convert(const fltSemantics &toSemantics, - roundingMode rounding_mode) + roundingMode rounding_mode) { lostFraction lostFraction; unsigned int newPartCount, oldPartCount; opStatus fs; - + lostFraction = lfExactlyZero; newPartCount = partCountForBits(toSemantics.precision + 1); oldPartCount = partCount(); @@ -1348,7 +1348,7 @@ (significandParts(), oldPartCount, toSemantics.precision); if (newPartCount == 1) { integerPart newPart = 0; - if (category==fcNormal || category==fcNaN) + if (category==fcNormal || category==fcNaN) newPart = significandParts()[0]; freeSignificand(); significand.part = newPart; @@ -1392,8 +1392,8 @@ round-to-zero to always be used. */ APFloat::opStatus APFloat::convertToInteger(integerPart *parts, unsigned int width, - bool isSigned, - roundingMode rounding_mode) const + bool isSigned, + roundingMode rounding_mode) const { lostFraction lost_fraction; unsigned int msb, partsCount; @@ -1463,7 +1463,7 @@ /* It takes exponent + 1 bits to represent the truncated floating point number without its sign. We lose a bit for the sign, but the maximally negative integer is a special case. */ - if(msb + 1 > width) /* !! Not same as msb >= width !! */ + if(msb + 1 > width) /* !! Not same as msb >= width !! */ return opInvalidOp; if(isSigned && msb + 1 == width @@ -1483,8 +1483,8 @@ APFloat::opStatus APFloat::convertFromUnsignedInteger(integerPart *parts, - unsigned int partCount, - roundingMode rounding_mode) + unsigned int partCount, + roundingMode rounding_mode) { unsigned int msb, precision; lostFraction lost_fraction; @@ -1510,8 +1510,8 @@ } APFloat::opStatus -APFloat::convertFromInteger(const integerPart *parts, unsigned int width, - bool isSigned, roundingMode rounding_mode) +APFloat::convertFromInteger(const integerPart *parts, unsigned int width, + bool isSigned, roundingMode rounding_mode) { unsigned int partCount = partCountForBits(width); opStatus status; @@ -1539,7 +1539,7 @@ APFloat::opStatus APFloat::convertFromHexadecimalString(const char *p, - roundingMode rounding_mode) + roundingMode rounding_mode) { lostFraction lost_fraction; integerPart *significand; @@ -1582,7 +1582,7 @@ } else { lost_fraction = trailingHexadecimalFraction(p, hex_value); while(hexDigitValue(*p) != -1U) - p++; + p++; break; } } @@ -1618,7 +1618,8 @@ } APFloat::opStatus -APFloat::convertFromString(const char *p, roundingMode rounding_mode) { +APFloat::convertFromString(const char *p, roundingMode rounding_mode) +{ /* Handle a leading minus sign. */ if(*p == '-') sign = 1, p++; @@ -1635,7 +1636,8 @@ // For good performance it is desirable for different APFloats // to produce different integers. uint32_t -APFloat::getHashValue() const { +APFloat::getHashValue() const +{ if (category==fcZero) return sign<<8 | semantics->precision ; else if (category==fcInfinity) return sign<<9 | semantics->precision; else if (category==fcNaN) return 1<<10 | semantics->precision; @@ -1658,7 +1660,8 @@ // the actual IEEE respresentations. We compensate for that here. APInt -APFloat::convertF80LongDoubleAPFloatToAPInt() const { +APFloat::convertF80LongDoubleAPFloatToAPInt() const +{ assert(semantics == (const llvm::fltSemantics* const)&x87DoubleExtended); assert (partCount()==2); @@ -1682,8 +1685,8 @@ assert(0); uint64_t words[2]; - words[0] = (((uint64_t)sign & 1) << 63) | - ((myexponent & 0x7fff) << 48) | + words[0] = (((uint64_t)sign & 1) << 63) | + ((myexponent & 0x7fff) << 48) | ((mysignificand >>16) & 0xffffffffffffLL); words[1] = mysignificand & 0xffff; APInt api(80, 2, words); @@ -1691,7 +1694,8 @@ } APInt -APFloat::convertDoubleAPFloatToAPInt() const { +APFloat::convertDoubleAPFloatToAPInt() const +{ assert(semantics == (const llvm::fltSemantics*)&IEEEdouble); assert (partCount()==1); @@ -1714,17 +1718,18 @@ } else assert(0); - APInt api(64, (((((uint64_t)sign & 1) << 63) | - ((myexponent & 0x7ff) << 52) | + APInt api(64, (((((uint64_t)sign & 1) << 63) | + ((myexponent & 0x7ff) << 52) | (mysignificand & 0xfffffffffffffLL)))); return api; } APInt -APFloat::convertFloatAPFloatToAPInt() const { +APFloat::convertFloatAPFloatToAPInt() const +{ assert(semantics == (const llvm::fltSemantics*)&IEEEsingle); assert (partCount()==1); - + uint32_t myexponent, mysignificand; if (category==fcNormal) { @@ -1744,32 +1749,36 @@ } else assert(0); - APInt api(32, (((sign&1) << 31) | ((myexponent&0xff) << 23) | + APInt api(32, (((sign&1) << 31) | ((myexponent&0xff) << 23) | (mysignificand & 0x7fffff))); return api; } APInt -APFloat::convertToAPInt() const { +APFloat::convertToAPInt() const +{ if (semantics == (const llvm::fltSemantics* const)&IEEEsingle) return convertFloatAPFloatToAPInt(); else if (semantics == (const llvm::fltSemantics* const)&IEEEdouble) return convertDoubleAPFloatToAPInt(); else if (semantics == (const llvm::fltSemantics* const)&x87DoubleExtended) return convertF80LongDoubleAPFloatToAPInt(); - else - assert(0); + + assert(0); + abort(); } -float -APFloat::convertToFloat() const { +float +APFloat::convertToFloat() const +{ assert(semantics == (const llvm::fltSemantics* const)&IEEEsingle); APInt api = convertToAPInt(); return api.bitsToFloat(); } -double -APFloat::convertToDouble() const { +double +APFloat::convertToDouble() const +{ assert(semantics == (const llvm::fltSemantics* const)&IEEEdouble); APInt api = convertToAPInt(); return api.bitsToDouble(); @@ -1781,7 +1790,8 @@ /// exponent = 0, integer bit set. (formerly "psuedodenormals") /// exponent!=0 nor all 1's, integer bit not set. (formerly "unnormals") void -APFloat::initFromF80LongDoubleAPInt(const APInt &api) { +APFloat::initFromF80LongDoubleAPInt(const APInt &api) +{ assert(api.getBitWidth()==80); uint64_t i1 = api.getRawData()[0]; uint64_t i2 = api.getRawData()[1]; @@ -1811,11 +1821,12 @@ significandParts()[1] = 0; if (myexponent==0) // denormal exponent = -16382; - } + } } void -APFloat::initFromDoubleAPInt(const APInt &api) { +APFloat::initFromDoubleAPInt(const APInt &api) +{ assert(api.getBitWidth()==64); uint64_t i = *api.getRawData(); uint64_t myexponent = (i >> 52) & 0x7ff; @@ -1843,11 +1854,12 @@ exponent = -1022; else *significandParts() |= 0x10000000000000LL; // integer bit - } + } } void -APFloat::initFromFloatAPInt(const APInt & api) { +APFloat::initFromFloatAPInt(const APInt & api) +{ assert(api.getBitWidth()==32); uint32_t i = (uint32_t)*api.getRawData(); uint32_t myexponent = (i >> 23) & 0xff; @@ -1883,7 +1895,8 @@ /// breaks when we get to PPC128 and IEEE128 (but both cannot exist in the /// same compile...) void -APFloat::initFromAPInt(const APInt& api) { +APFloat::initFromAPInt(const APInt& api) +{ if (api.getBitWidth() == 32) return initFromFloatAPInt(api); else if (api.getBitWidth()==64) @@ -1894,17 +1907,19 @@ assert(0); } -APFloat::APFloat(const APInt& api) { +APFloat::APFloat(const APInt& api) +{ initFromAPInt(api); } -APFloat::APFloat(float f) { +APFloat::APFloat(float f) +{ APInt api = APInt(32, 0); initFromAPInt(api.floatToBits(f)); } -APFloat::APFloat(double d) { +APFloat::APFloat(double d) +{ APInt api = APInt(64, 0); initFromAPInt(api.doubleToBits(d)); } - From neil at daikokuya.co.uk Wed Sep 26 14:35:06 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Wed, 26 Sep 2007 21:35:06 -0000 Subject: [llvm-commits] [llvm] r42374 - /llvm/trunk/include/llvm/ADT/APFloat.h Message-ID: <200709262135.l8QLZ6Bj026617@zion.cs.uiuc.edu> Author: neil Date: Wed Sep 26 16:35:05 2007 New Revision: 42374 URL: http://llvm.org/viewvc/llvm-project?rev=42374&view=rev Log: Whitespace cleanup. Modified: llvm/trunk/include/llvm/ADT/APFloat.h Modified: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=42374&r1=42373&r2=42374&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (original) +++ llvm/trunk/include/llvm/ADT/APFloat.h Wed Sep 26 16:35:05 2007 @@ -63,12 +63,12 @@ right so that the exponent is maintained at the format's minimum, so that the smallest denormal has just the least significant bit of the significand set. The sign of zeroes and infinities is - significant; the exponent and significand of such numbers is - not stored, but has a known implicit (deterministic) value: - 0 for the significands, 0 for zero exponent, all 1 bits for - infinity exponent. For NaNs the sign and significand are - deterministic, although not really meaningful; the exponent is - implicitly all 1 bits. + significant; the exponent and significand of such numbers is not + stored, but has a known implicit (deterministic) value: 0 for the + significands, 0 for zero exponent, all 1 bits for infinity + exponent. For NaNs the sign and significand are deterministic, + although not really meaningful, and preserved in non-conversion + operations. The exponent is implicitly all 1 bits. TODO ==== @@ -87,7 +87,7 @@ from extended exponent range) and IBM two-double extended precision (hard). - New operations: sqrt, copysign, nextafter, nexttoward. + New operations: sqrt, nextafter, nexttoward. */ #ifndef LLVM_FLOAT_H @@ -200,7 +200,7 @@ so we won't use operator==. Use one of the following, or write whatever it is you really mean. */ // bool operator==(const APFloat &) const; // DO NOT IMPLEMENT - + /* IEEE comparison with another floating point number (NaNs compare unordered, 0==-0). */ cmpResult compare(const APFloat &) const; @@ -285,7 +285,7 @@ exponent_t exponent; /* What kind of floating point number this is. */ - /* Only 2 bits are required, but VisualStudio incorrectly sign extends + /* Only 2 bits are required, but VisualStudio incorrectly sign extends it. Using the extra bit keeps it from failing under VisualStudio */ fltCategory category: 3; From evan.cheng at apple.com Wed Sep 26 14:36:17 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Sep 2007 21:36:17 -0000 Subject: [llvm-commits] [llvm] r42375 - in /llvm/trunk/lib: CodeGen/SelectionDAG/ScheduleDAG.cpp CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Target/MRegisterInfo.cpp Message-ID: <200709262136.l8QLaHQ0026693@zion.cs.uiuc.edu> Author: evancheng Date: Wed Sep 26 16:36:17 2007 New Revision: 42375 URL: http://llvm.org/viewvc/llvm-project?rev=42375&view=rev Log: - Move getPhysicalRegisterRegClass() from ScheduleDAG to MRegisterInfo. - Added ability to emit cross class register copies to the BBRU scheduler. - More aggressive backtracking. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp llvm/trunk/lib/Target/MRegisterInfo.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=42375&r1=42374&r2=42375&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Wed Sep 26 16:36:17 2007 @@ -28,24 +28,6 @@ using namespace llvm; -/// getPhysicalRegisterRegClass - Returns the Register Class of a physical -/// register. -static const TargetRegisterClass *getPhysicalRegisterRegClass( - const MRegisterInfo *MRI, - MVT::ValueType VT, - unsigned reg) { - assert(MRegisterInfo::isPhysicalRegister(reg) && - "reg must be a physical register"); - // Pick the register class of the right type that contains this physreg. - for (MRegisterInfo::regclass_iterator I = MRI->regclass_begin(), - E = MRI->regclass_end(); I != E; ++I) - if ((*I)->hasType(VT) && (*I)->contains(reg)) - return *I; - assert(false && "Couldn't find the register class"); - return 0; -} - - /// CheckForPhysRegDependency - Check if the dependency between def and use of /// a specified operand is a physical register dependency. If so, returns the /// register and the cost of copying the register. @@ -67,7 +49,7 @@ II.ImplicitDefs[ResNo - II.numDefs] == Reg) { PhysReg = Reg; const TargetRegisterClass *RC = - getPhysicalRegisterRegClass(MRI, Def->getValueType(ResNo), Reg); + MRI->getPhysicalRegisterRegClass(Def->getValueType(ResNo), Reg); Cost = RC->getCopyCost(); } } @@ -356,7 +338,7 @@ if (VRBase) TRC = RegMap->getRegClass(VRBase); else - TRC = getPhysicalRegisterRegClass(MRI, Node->getValueType(ResNo), SrcReg); + TRC = MRI->getPhysicalRegisterRegClass(Node->getValueType(ResNo), SrcReg); // If all uses are reading from the src physical register and copying the // register is either impossible or very expensive, then don't create a copy. @@ -766,8 +748,8 @@ if (MRegisterInfo::isVirtualRegister(InReg)) TRC = RegMap->getRegClass(InReg); else - TRC = getPhysicalRegisterRegClass(MRI, - Node->getOperand(2).getValueType(), + TRC = + MRI->getPhysicalRegisterRegClass(Node->getOperand(2).getValueType(), InReg); MRI->copyRegToReg(*BB, BB->end(), DestReg, InReg, TRC, TRC); } @@ -845,6 +827,39 @@ TII->insertNoop(*BB, BB->end()); } +void ScheduleDAG::EmitCrossRCCopy(SUnit *SU, DenseMap &VRBaseMap) { + for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); + I != E; ++I) { + if (I->isCtrl) continue; // ignore chain preds + if (!I->Dep->Node) { + // Copy to physical register. + DenseMap::iterator VRI = VRBaseMap.find(I->Dep); + assert(VRI != VRBaseMap.end() && "Node emitted out of order - late"); + // Find the destination physical register. + unsigned Reg = 0; + for (SUnit::const_succ_iterator II = SU->Succs.begin(), + EE = SU->Succs.end(); II != EE; ++II) { + if (I->Reg) { + Reg = I->Reg; + break; + } + } + assert(I->Reg && "Unknown physical register!"); + MRI->copyRegToReg(*BB, BB->end(), Reg, VRI->second, + SU->CopyDstRC, SU->CopySrcRC); + } else { + // Copy from physical register. + assert(I->Reg && "Unknown physical register!"); + unsigned VRBase = RegMap->createVirtualRegister(SU->CopyDstRC); + bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)); + assert(isNew && "Node emitted out of order - early"); + MRI->copyRegToReg(*BB, BB->end(), VRBase, I->Reg, + SU->CopyDstRC, SU->CopySrcRC); + } + break; + } +} + /// EmitSchedule - Emit the machine code in scheduled order. void ScheduleDAG::EmitSchedule() { // If this is the first basic block in the function, and if it has live ins @@ -864,11 +879,15 @@ // Finally, emit the code for all of the scheduled instructions. DenseMap VRBaseMap; + DenseMap CopyVRBaseMap; for (unsigned i = 0, e = Sequence.size(); i != e; i++) { if (SUnit *SU = Sequence[i]) { for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; ++j) EmitNode(SU->FlaggedNodes[j], SU->InstanceNo, VRBaseMap); - EmitNode(SU->Node, SU->InstanceNo, VRBaseMap); + if (SU->Node) + EmitNode(SU->Node, SU->InstanceNo, VRBaseMap); + else + EmitCrossRCCopy(SU, CopyVRBaseMap); } else { // Null SUnit* is a noop. EmitNoop(); @@ -903,7 +922,10 @@ /// a group of nodes flagged together. void SUnit::dump(const SelectionDAG *G) const { cerr << "SU(" << NodeNum << "): "; - Node->dump(G); + if (Node) + Node->dump(G); + else + cerr << "CROSS RC COPY "; cerr << "\n"; if (FlaggedNodes.size() != 0) { for (unsigned i = 0, e = FlaggedNodes.size(); i != e; i++) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=42375&r1=42374&r2=42375&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Sep 26 16:36:17 2007 @@ -78,15 +78,18 @@ void Schedule(); private: - void ReleasePred(SUnit *PredSU, bool isChain, unsigned CurCycle); - void ReleaseSucc(SUnit *SuccSU, bool isChain, unsigned CurCycle); - void CapturePred(SUnit *PredSU, SUnit *SU, bool isChain); - void ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle); - void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); - void UnscheduleNodeBottomUp(SUnit *SU); - SUnit *BackTrackBottomUp(SUnit*, unsigned, unsigned&, bool&); - SUnit *CopyAndMoveSuccessors(SUnit *SU); - bool DelayForLiveRegsBottomUp(SUnit *SU, unsigned &CurCycle); + void ReleasePred(SUnit*, bool, unsigned); + void ReleaseSucc(SUnit*, bool isChain, unsigned); + void CapturePred(SUnit*, SUnit*, bool); + void ScheduleNodeBottomUp(SUnit*, unsigned); + void ScheduleNodeTopDown(SUnit*, unsigned); + void UnscheduleNodeBottomUp(SUnit*); + void BacktrackBottomUp(SUnit*, unsigned, unsigned&); + SUnit *CopyAndMoveSuccessors(SUnit*); + SUnit *InsertCopiesAndMoveSuccs(SUnit*, unsigned, + const TargetRegisterClass*, + const TargetRegisterClass*); + bool DelayForLiveRegsBottomUp(SUnit*, unsigned&); void ListScheduleTopDown(); void ListScheduleBottomUp(); void CommuteNodesToReducePressure(); @@ -136,7 +139,7 @@ SmallPtrSet OperandSeen; for (unsigned i = Sequence.size()-1; i != 0; --i) { // Ignore first node. SUnit *SU = Sequence[i]; - if (!SU) continue; + if (!SU || !SU->Node) continue; if (SU->isCommutable) { unsigned Opc = SU->Node->getTargetOpcode(); unsigned NumRes = TII->getNumDefs(Opc); @@ -209,7 +212,7 @@ if ((PredSU->NumSuccsLeft + PredSU->NumChainSuccsLeft) == 0) { // EntryToken has to go last! Special case it here. - if (PredSU->Node->getOpcode() != ISD::EntryToken) { + if (!PredSU->Node || PredSU->Node->getOpcode() != ISD::EntryToken) { PredSU->isAvailable = true; AvailableQueue->push(PredSU); } @@ -323,18 +326,18 @@ AvailableQueue->push(SU); } -/// BackTrackBottomUp - Back track scheduling to a previous cycle specified in +/// BacktrackBottomUp - Backtrack scheduling to a previous cycle specified in /// BTCycle in order to schedule a specific node. Returns the last unscheduled /// SUnit. Also returns if a successor is unscheduled in the process. -SUnit *ScheduleDAGRRList::BackTrackBottomUp(SUnit *SU, unsigned BTCycle, - unsigned &CurCycle, bool &SuccUnsched) { - SuccUnsched = false; +void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle, + unsigned &CurCycle) { SUnit *OldSU = NULL; - while (CurCycle > BTCycle) { + while (CurCycle > BtCycle) { OldSU = Sequence.back(); Sequence.pop_back(); if (SU->isSucc(OldSU)) - SuccUnsched = true; + // Don't try to remove SU from AvailableQueue. + SU->isAvailable = false; UnscheduleNodeBottomUp(OldSU); --CurCycle; } @@ -344,14 +347,15 @@ assert(false && "Something is wrong!"); abort(); } - - return OldSU; } /// isSafeToCopy - True if the SUnit for the given SDNode can safely cloned, /// i.e. the node does not produce a flag, it does not read a flag and it does /// not have an incoming chain. static bool isSafeToCopy(SDNode *N) { + if (!N) + return true; + for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) if (N->getValueType(i) == MVT::Flag) return false; @@ -368,6 +372,8 @@ /// CopyAndMoveSuccessors - Clone the specified node and move its scheduled /// successors to the newly created node. SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) { + DOUT << "Duplicating SU # " << SU->NodeNum << "\n"; + SUnit *NewSU = Clone(SU); // New SUnit has the exact same predecessors. @@ -403,6 +409,88 @@ return NewSU; } +/// InsertCopiesAndMoveSuccs - Insert expensive cross register class copies and +/// move all scheduled successors of the given SUnit to the last copy. +SUnit *ScheduleDAGRRList::InsertCopiesAndMoveSuccs(SUnit *SU, unsigned Reg, + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) { + SUnit *CopyFromSU = NewSUnit(NULL); + CopyFromSU->CopySrcRC = SrcRC; + CopyFromSU->CopyDstRC = DestRC; + CopyFromSU->Depth = SU->Depth; + CopyFromSU->Height = SU->Height; + + SUnit *CopyToSU = NewSUnit(NULL); + CopyToSU->CopySrcRC = DestRC; + CopyToSU->CopyDstRC = SrcRC; + + // Only copy scheduled successors. Cut them from old node's successor + // list and move them over. + SmallVector DelDeps; + for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); + I != E; ++I) { + if (I->isSpecial) + continue; + CopyToSU->Height = std::max(CopyToSU->Height, I->Dep->Height+1); + if (I->Dep->isScheduled) { + I->Dep->addPred(CopyToSU, I->isCtrl, false, I->Reg, I->Cost); + DelDeps.push_back(I); + } + } + for (unsigned i = 0, e = DelDeps.size(); i != e; ++i) { + SUnit *Succ = DelDeps[i]->Dep; + bool isCtrl = DelDeps[i]->isCtrl; + Succ->removePred(SU, isCtrl, false); + } + + CopyFromSU->addPred(SU, false, false, Reg, -1); + CopyToSU->addPred(CopyFromSU, false, false, Reg, 1); + + AvailableQueue->updateNode(SU); + AvailableQueue->addNode(CopyFromSU); + AvailableQueue->addNode(CopyToSU); + + return CopyToSU; +} + +/// getPhysicalRegisterVT - Returns the ValueType of the physical register +/// definition of the specified node. +/// FIXME: Move to SelectionDAG? +static MVT::ValueType getPhysicalRegisterVT(SDNode *N, unsigned Reg, + const TargetInstrInfo *TII) { + const TargetInstrDescriptor &TID = TII->get(N->getTargetOpcode()); + assert(TID.ImplicitDefs && "Physical reg def must be in implicit def list!"); + unsigned NumRes = TID.numDefs; + for (const unsigned *ImpDef = TID.ImplicitDefs; *ImpDef; ++ImpDef) { + if (Reg == *ImpDef) + break; + ++NumRes; + } + return N->getValueType(NumRes); +} + +// FIXME: This is probably too slow! +static void isReachable(SUnit *SU, SUnit *TargetSU, + SmallPtrSet &Visited, bool &Reached) { + if (Reached) return; + if (SU == TargetSU) { + Reached = true; + return; + } + if (!Visited.insert(SU)) return; + + for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; + ++I) + isReachable(I->Dep, TargetSU, Visited, Reached); +} + +static bool isReachable(SUnit *SU, SUnit *TargetSU) { + SmallPtrSet Visited; + bool Reached = false; + isReachable(SU, TargetSU, Visited, Reached); + return Reached; +} + /// DelayForLiveRegsBottomUp - Returns true if it is necessary to delay /// scheduling of the given node to satisfy live physical register dependencies. /// If the specific node is the last one that's available to schedule, do @@ -431,7 +519,7 @@ for (unsigned i = 0, e = SU->FlaggedNodes.size()+1; i != e; ++i) { SDNode *Node = (i == 0) ? SU->Node : SU->FlaggedNodes[i-1]; - if (!Node->isTargetOpcode()) + if (!Node || !Node->isTargetOpcode()) continue; const TargetInstrDescriptor &TID = TII->get(Node->getTargetOpcode()); if (!TID.ImplicitDefs) @@ -458,9 +546,12 @@ LiveCycle = std::min(LiveCycle, LCycle); } - if (SU->CycleBound < LiveCycle) { - bool SuccUnsched = false; - SUnit *OldSU = BackTrackBottomUp(SU, LiveCycle, CurCycle, SuccUnsched); + SUnit *OldSU = Sequence[LiveCycle]; + if (!isReachable(Sequence[LiveCycle], SU)) { + // If CycleBound is greater than backtrack cycle, then some of SU + // successors are going to be unscheduled. + bool SuccUnsched = SU->CycleBound > LiveCycle; + BacktrackBottomUp(SU, LiveCycle, CurCycle); // Force the current node to be scheduled before the node that // requires the physical reg dep. if (OldSU->isAvailable) { @@ -474,20 +565,31 @@ } else { // Try duplicating the nodes that produces these "expensive to copy" // values to break the dependency. - for (unsigned i = 0, e = LRegs.size(); i != e; ++i) { - unsigned Reg = LRegs[i]; - SUnit *LRDef = LiveRegDefs[Reg]; - if (isSafeToCopy(LRDef->Node)) { - SUnit *NewDef = CopyAndMoveSuccessors(LRDef); - LiveRegDefs[Reg] = NewDef; - NewDef->addPred(SU, true, true); - SU->isAvailable = false; - AvailableQueue->push(NewDef); - } else { - assert(false && "Expensive copying is required?"); + assert(LRegs.size() == 1 && "Can't handle this yet!"); + unsigned Reg = LRegs[0]; + SUnit *LRDef = LiveRegDefs[Reg]; + SUnit *NewDef; + if (isSafeToCopy(LRDef->Node)) + NewDef = CopyAndMoveSuccessors(LRDef); + else { + // Issue expensive cross register class copies. + MVT::ValueType VT = getPhysicalRegisterVT(LRDef->Node, Reg, TII); + const TargetRegisterClass *RC = + MRI->getPhysicalRegisterRegClass(VT, Reg); + const TargetRegisterClass *DestRC = MRI->getCrossCopyRegClass(RC); + if (!DestRC) { + assert(false && "Don't know how to copy this physical register!"); abort(); } + NewDef = InsertCopiesAndMoveSuccs(LRDef,Reg,DestRC,RC); } + + DOUT << "Adding an edge from SU # " << SU->NodeNum + << " to SU #" << NewDef->NodeNum << "\n"; + LiveRegDefs[Reg] = NewDef; + NewDef->addPred(SU, true, true); + SU->isAvailable = false; + AvailableQueue->push(NewDef); return true; } } @@ -710,7 +812,7 @@ static inline bool isCopyFromLiveIn(const SUnit *SU) { SDNode *N = SU->Node; - return N->getOpcode() == ISD::CopyFromReg && + return N && N->getOpcode() == ISD::CopyFromReg && N->getOperand(N->getNumOperands()-1).getValueType() != MVT::Flag; } @@ -822,7 +924,7 @@ unsigned getNodePriority(const SUnit *SU) const { assert(SU->NodeNum < SethiUllmanNumbers.size()); - unsigned Opc = SU->Node->getOpcode(); + unsigned Opc = SU->Node ? SU->Node->getOpcode() : 0; if (Opc == ISD::CopyFromReg && !isCopyFromLiveIn(SU)) // CopyFromReg should be close to its def because it restricts // allocation choices. But if it is a livein then perhaps we want it @@ -912,7 +1014,7 @@ unsigned Cycle = I->Dep->Cycle; // If there are bunch of CopyToRegs stacked up, they should be considered // to be at the same position. - if (I->Dep->Node->getOpcode() == ISD::CopyToReg) + if (I->Dep->Node && I->Dep->Node->getOpcode() == ISD::CopyToReg) Cycle = closestSucc(I->Dep)+1; if (Cycle > MaxCycle) MaxCycle = Cycle; @@ -928,13 +1030,13 @@ for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { if (I->isCtrl) continue; // ignore chain preds - if (I->Dep->Node->getOpcode() != ISD::CopyFromReg) + if (!I->Dep->Node || I->Dep->Node->getOpcode() != ISD::CopyFromReg) Scratches++; } for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { if (I->isCtrl) continue; // ignore chain succs - if (I->Dep->Node->getOpcode() != ISD::CopyToReg) + if (!I->Dep->Node || I->Dep->Node->getOpcode() != ISD::CopyToReg) Scratches += 10; } return Scratches; @@ -1004,28 +1106,6 @@ return false; } -// FIXME: This is probably too slow! -static void isReachable(SUnit *SU, SUnit *TargetSU, - SmallPtrSet &Visited, bool &Reached) { - if (Reached) return; - if (SU == TargetSU) { - Reached = true; - return; - } - if (!Visited.insert(SU)) return; - - for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; - ++I) - isReachable(I->Dep, TargetSU, Visited, Reached); -} - -static bool isReachable(SUnit *SU, SUnit *TargetSU) { - SmallPtrSet Visited; - bool Reached = false; - isReachable(SU, TargetSU, Visited, Reached); - return Reached; -} - template bool BURegReductionPriorityQueue::canClobber(SUnit *SU, SUnit *Op) { if (SU->isTwoAddress) { @@ -1056,7 +1136,7 @@ continue; SDNode *Node = SU->Node; - if (!Node->isTargetOpcode()) + if (!Node || !Node->isTargetOpcode()) continue; unsigned Opc = Node->getTargetOpcode(); @@ -1152,8 +1232,8 @@ bool td_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const { unsigned LPriority = SPQ->getNodePriority(left); unsigned RPriority = SPQ->getNodePriority(right); - bool LIsTarget = left->Node->isTargetOpcode(); - bool RIsTarget = right->Node->isTargetOpcode(); + bool LIsTarget = left->Node && left->Node->isTargetOpcode(); + bool RIsTarget = right->Node && right->Node->isTargetOpcode(); bool LIsFloater = LIsTarget && left->NumPreds == 0; bool RIsFloater = RIsTarget && right->NumPreds == 0; unsigned LBonus = (SumOfUnscheduledPredsOfSuccs(left) == 1) ? 2 : 0; @@ -1210,7 +1290,7 @@ if (SethiUllmanNumber != 0) return SethiUllmanNumber; - unsigned Opc = SU->Node->getOpcode(); + unsigned Opc = SU->Node ? SU->Node->getOpcode() : 0; if (Opc == ISD::TokenFactor || Opc == ISD::CopyToReg) SethiUllmanNumber = 0xffff; else if (SU->NumSuccsLeft == 0) Modified: llvm/trunk/lib/Target/MRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MRegisterInfo.cpp?rev=42375&r1=42374&r2=42375&view=diff ============================================================================== --- llvm/trunk/lib/Target/MRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/MRegisterInfo.cpp Wed Sep 26 16:36:17 2007 @@ -34,6 +34,21 @@ MRegisterInfo::~MRegisterInfo() {} +/// getPhysicalRegisterRegClass - Returns the Register Class of a physical +/// register. +const TargetRegisterClass * +MRegisterInfo::getPhysicalRegisterRegClass(MVT::ValueType VT, + unsigned reg) const { + assert(isPhysicalRegister(reg) && "reg must be a physical register"); + // Pick the register class of the right type that contains this physreg. + for (regclass_iterator I = regclass_begin(), E = regclass_end(); I != E; ++I) + if ((*I)->hasType(VT) && (*I)->contains(reg)) + return *I; + assert(false && "Couldn't find the register class"); + return 0; +} + + /// getAllocatableSetForRC - Toggle the bits that represent allocatable /// registers for the specific register class. static void getAllocatableSetForRC(MachineFunction &MF, From evan.cheng at apple.com Wed Sep 26 14:38:03 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Sep 2007 21:38:03 -0000 Subject: [llvm-commits] [llvm] r42377 - /llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200709262138.l8QLc3qj026784@zion.cs.uiuc.edu> Author: evancheng Date: Wed Sep 26 16:38:03 2007 New Revision: 42377 URL: http://llvm.org/viewvc/llvm-project?rev=42377&view=rev Log: Oops. Forgot this. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=42377&r1=42376&r2=42377&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Wed Sep 26 16:38:03 2007 @@ -33,6 +33,7 @@ class TargetInstrInfo; class TargetInstrDescriptor; class TargetMachine; + class TargetRegisterClass; /// HazardRecognizer - This determines whether or not an instruction can be /// issued this cycle, and whether or not a noop needs to be inserted to handle @@ -124,6 +125,8 @@ unsigned Cycle; // Once scheduled, the cycle of the op. unsigned Depth; // Node depth; unsigned Height; // Node height; + const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null. + const TargetRegisterClass *CopySrcRC; SUnit(SDNode *node, unsigned nodenum) : Node(node), InstanceNo(0), NodeNum(nodenum), Latency(0), @@ -131,7 +134,8 @@ NumChainPredsLeft(0), NumChainSuccsLeft(0), isTwoAddress(false), isCommutable(false), hasImplicitDefs(false), isPending(false), isAvailable(false), isScheduled(false), - CycleBound(0), Cycle(0), Depth(0), Height(0) {} + CycleBound(0), Cycle(0), Depth(0), Height(0), + CopyDstRC(NULL), CopySrcRC(NULL) {} /// addPred - This adds the specified node as a pred of the current node if /// not already. This returns true if this is a new pred. @@ -332,6 +336,8 @@ /// void EmitNoop(); + void EmitCrossRCCopy(SUnit *SU, DenseMap &VRBaseMap); + /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an /// implicit physical register output. void EmitCopyFromReg(SDNode *Node, unsigned ResNo, unsigned InstNo, From asl at math.spbu.ru Wed Sep 26 14:43:28 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Wed, 26 Sep 2007 21:43:28 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42378 - /llvm-gcc-4.0/trunk/gcc/config/darwin.h Message-ID: <200709262143.l8QLhSCH027029@zion.cs.uiuc.edu> Author: asl Date: Wed Sep 26 16:43:28 2007 New Revision: 42378 URL: http://llvm.org/viewvc/llvm-project?rev=42378&view=rev Log: Fix 4.0 vs 4.2 difference in arguments. Modified: llvm-gcc-4.0/trunk/gcc/config/darwin.h Modified: llvm-gcc-4.0/trunk/gcc/config/darwin.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/config/darwin.h?rev=42378&r1=42377&r2=42378&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/config/darwin.h (original) +++ llvm-gcc-4.0/trunk/gcc/config/darwin.h Wed Sep 26 16:43:28 2007 @@ -798,7 +798,7 @@ do { \ if (darwin_macosx_version_min \ && strverscmp (darwin_macosx_version_min, "10.3") < 0) \ - warning (0, "Mac OS X version 10.3 or later is needed instead of %s for objc/obj-c++ exceptions", \ + warning ("Mac OS X version 10.3 or later is needed instead of %s for objc/obj-c++ exceptions", \ darwin_macosx_version_min); \ } while(0) /* APPLE LOCAL end radar 4590191 */ From asl at math.spbu.ru Wed Sep 26 14:43:55 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Thu, 27 Sep 2007 01:43:55 +0400 Subject: [llvm-commits] [llvm-gcc-4.0] r42353 - in /llvm-gcc-4.0/trunk/gcc: config/alpha/unicosmk.h config/darwin.h objc/objc-act.c In-Reply-To: <4B72D5FA-1E0D-4A58-949F-51C00F58406E.SS832SS@apple.com> References: <200709260906.l8Q960Pr001546@zion.cs.uiuc.edu> <4B72D5FA-1E0D-4A58-949F-51C00F58406E.SS832SS@apple.com> Message-ID: <1190843035.11109.0.camel@asl.dorms.spbu.ru> Hello, Devang. > This breaks bootstrap on darwin. Fixed! Please verify. -- With best regards, Anton Korobeynikov. Faculty of Mathematics & Mechanics, Saint Petersburg State University. From isanbard at gmail.com Wed Sep 26 14:45:52 2007 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 Sep 2007 21:45:52 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42379 - /llvm-gcc-4.0/trunk/build_gcc Message-ID: <200709262145.l8QLjrgm027096@zion.cs.uiuc.edu> Author: void Date: Wed Sep 26 16:45:52 2007 New Revision: 42379 URL: http://llvm.org/viewvc/llvm-project?rev=42379&view=rev Log: Warnings okay during debug build. Modified: llvm-gcc-4.0/trunk/build_gcc Modified: llvm-gcc-4.0/trunk/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/build_gcc?rev=42379&r1=42378&r2=42379&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/build_gcc (original) +++ llvm-gcc-4.0/trunk/build_gcc Wed Sep 26 16:45:52 2007 @@ -170,7 +170,13 @@ # These are the configure and build flags that are used. # APPLE LOCAL begin LLVM Support for non /usr $DEST_ROOT, use libstdc++ -CONFIGFLAGS="--disable-checking --enable-werror \ +if [ "x$LLVM_DEBUG" == "x" ]; then + CHECKING_FLAGS="--disable-checking --enable-werror" +else + CHECKING_FLAGS="--enable-checking" +fi + +CONFIGFLAGS="$CHECKING_FLAGS \ --prefix=$DEST_ROOT \ --mandir=$LLVM_INSTALL_PREFIX/share/man \ --enable-languages=c,objc,c++,obj-c++ \ @@ -298,7 +304,12 @@ mkdir -p $DIR/obj-$BUILD-$t $DIR/dst-$BUILD-$t || exit 1 cd $DIR/obj-$BUILD-$t || exit 1 if [ \! -f Makefile ]; then - $SRC_DIR/configure $CONFIGFLAGS --enable-werror-always \ + if [ "x$LLVM_DEBUG" == "x" ]; then + WERROR_FLAGS="--enable-werror-always" + else + WERROR_FLAGS="" + fi + $SRC_DIR/configure $CONFIGFLAGS $WERROR_FLAGS \ `if [ $t = i686 ] ; then echo $I386_CPU ; fi` \ --program-prefix=$t-apple-darwin$DARWIN_VERS- \ --host=$BUILD-apple-darwin$DARWIN_VERS --target=$t-apple-darwin$DARWIN_VERS || exit 1 From dalej at apple.com Wed Sep 26 14:50:08 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 26 Sep 2007 14:50:08 -0700 Subject: [llvm-commits] [llvm] r42373 - /llvm/trunk/lib/Support/APFloat.cpp In-Reply-To: <200709262133.l8QLXgdx026535@zion.cs.uiuc.edu> References: <200709262133.l8QLXgdx026535@zion.cs.uiuc.edu> Message-ID: <0DAAAA07-62A3-4859-B95B-B6CDB1EE1679@apple.com> > > APFloat::opStatus > -APFloat::convertFromString(const char *p, roundingMode > rounding_mode) { > +APFloat::convertFromString(const char *p, roundingMode rounding_mode) > +{ Most of llvm uses the K&R style here. I don't care though, do you Chris? From evan.cheng at apple.com Wed Sep 26 14:50:16 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Sep 2007 14:50:16 -0700 Subject: [llvm-commits] [llvm] r42285 - in /llvm/trunk/lib/Target/X86: X86FloatingPoint.cpp X86ISelLowering.cpp X86ISelLowering.h X86InstrFPStack.td X86InstrInfo.cpp X86InstrInfo.td X86InstrSSE.td X86InstrX86-64.td X86RegisterInfo.cpp In-Reply-To: <20070925172226.GB21991@village.us.cray.com> References: <20070925172226.GB21991@village.us.cray.com> Message-ID: <1D0FDDB3-5396-480B-86EE-E2BF7C326F91@apple.com> On Sep 25, 2007, at 10:22 AM, Dan Gohman wrote: >> +def X86cmp_new : SDNode<"X86ISD::CMP_NEW" , SDTX86CmpTest>; > > X86ISD::CMP_NEW SelectionDAG nodes return an i32 flags value, > however the > corresponding X86cmp_new pattern-matching nodes use SDTX86CmpTest, > which has > no result values. Is this intentional? If so, how is the discrepancy > handled? X86ISD::CMP_NEW does *not* return an flag result. It returns an result in a physical register EFLAGS. It's up to the scheduler to ensure nothing that can potentially modify EFLAGS is scheduled between CMP_NEW and its users. The goal of what I've been doing is to eliminate the need for the MVT::Flag hackery (which prevents SDNode CSE, scheduling, etc.). > > >> +def : Pat<(parallel (X86cmp_new GR8:$src1, 0), (implicit EFLAGS)), >> + (NEW_TEST8rr GR8:$src1, GR8:$src1)>; > > In the SelectionDAG IR, an SDNode can return multiple results. > However, in > this GCC-RTL-like pattern langauge, where many things are supposed > to directly > correspond to SelectionDAG counterparts, nodes can return at most > one result. > They must be grouped together in a parallel to represent operations > that have > multiple results. It seems like this will result in more > discrepancies. Am I > misunderstanding something? Again, no discrepancies. Instruction NEW_TEST8rr produces an implicit result in EFLAGS. What the pattern is saying is the target independent node expects the implicit result EFLAGS to be modeled as an explicit result. BTW, I intend to get rid of "parallel". I just haven't gotten around to it. Evan > > > 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 isanbard at gmail.com Wed Sep 26 15:11:38 2007 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 Sep 2007 22:11:38 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r42381 - /llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Message-ID: <200709262211.l8QMBdWx028192@zion.cs.uiuc.edu> Author: void Date: Wed Sep 26 17:11:38 2007 New Revision: 42381 URL: http://llvm.org/viewvc/llvm-project?rev=42381&view=rev Log: Instead of the expensive "strstr" check, just do a "strncmp". 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=42381&r1=42380&r2=42381&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Wed Sep 26 17:11:38 2007 @@ -11683,7 +11683,8 @@ bool objc_is_protocol_reference (const char *name) { - return flag_objc_abi == 2 && strstr (name, "_OBJC_PROTOCOL_$_") != 0; + return flag_objc_abi == 2 && strlen (name) > 19 && + strncmp (name, "\01L_OBJC_PROTOCOL_$_", 19) == 0; } #endif /* APPLE LOCAL end - LLVM radar 5476262 */ From gordonhenriksen at mac.com Wed Sep 26 15:44:45 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Wed, 26 Sep 2007 22:44:45 -0000 Subject: [llvm-commits] [llvm] r42382 - /llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Message-ID: <200709262244.l8QMijkF029297@zion.cs.uiuc.edu> Author: gordon Date: Wed Sep 26 17:44:45 2007 New Revision: 42382 URL: http://llvm.org/viewvc/llvm-project?rev=42382&view=rev Log: Updating LLVM.xcodeproj. 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=42382&r1=42381&r2=42382&view=diff ============================================================================== --- llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj (original) +++ llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Wed Sep 26 17:44:45 2007 @@ -163,6 +163,15 @@ 9FD3E58E0CA0125F00E54D15 /* Core.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Core.h; sourceTree = ""; }; 9FD3E5900CA0129D00E54D15 /* Core.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Core.cpp; path = ../lib/VMCore/Core.cpp; sourceTree = SOURCE_ROOT; }; 9FD3E5920CA012B300E54D15 /* BitWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BitWriter.cpp; sourceTree = ""; }; + 9FE25D900CAB166D005383FC /* APFloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APFloat.h; sourceTree = ""; }; + 9FE25D910CAB166D005383FC /* SparseBitVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SparseBitVector.h; sourceTree = ""; }; + 9FE25D920CAB169F005383FC /* RegisterCoalescer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterCoalescer.h; sourceTree = ""; }; + 9FE25D930CAB16D8005383FC /* PostDominatorCalculation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PostDominatorCalculation.h; sourceTree = ""; }; + 9FE25D940CAB16FB005383FC /* RegisterCoalescer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterCoalescer.cpp; sourceTree = ""; }; + 9FE25D950CAB1724005383FC /* APFloat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = APFloat.cpp; sourceTree = ""; }; + 9FE25D960CAB1759005383FC /* TargetCallingConv.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TargetCallingConv.td; sourceTree = ""; }; + 9FE25D970CAB17F9005383FC /* DominatorCalculation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DominatorCalculation.h; path = ../lib/VMCore/DominatorCalculation.h; sourceTree = SOURCE_ROOT; }; + 9FE25D980CAB17F9005383FC /* DominatorInternals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DominatorInternals.cpp; path = ../lib/VMCore/DominatorInternals.cpp; sourceTree = SOURCE_ROOT; }; 9FE4508B0C77A77000C4FEA4 /* ARMCodeEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ARMCodeEmitter.cpp; sourceTree = ""; }; 9FE4508C0C77A77000C4FEA4 /* ARMGenAsmWriter.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenAsmWriter.inc; sourceTree = ""; }; 9FE4508D0C77A77000C4FEA4 /* ARMGenDAGISel.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenDAGISel.inc; sourceTree = ""; }; @@ -1042,7 +1051,7 @@ isa = PBXGroup; children = ( DE66F1E908ABF03100323D32 /* include/llvm */, - CF8F1B480B64F7AB00BB4199 /* llvm-c */, + CF8F1B480B64F7AB00BB4199 /* include/llvm-c */, DE66ECBD08ABEC0700323D32 /* lib/Analysis */, 9FE450DE0C77ABE400C4FEA4 /* lib/Archive */, DE66EC8808ABEAC900323D32 /* lib/AsmParser */, @@ -1207,14 +1216,14 @@ path = ../lib/Archive; sourceTree = SOURCE_ROOT; }; - CF8F1B480B64F7AB00BB4199 /* llvm-c */ = { + CF8F1B480B64F7AB00BB4199 /* include/llvm-c */ = { isa = PBXGroup; children = ( 9FD3E58D0CA0125F00E54D15 /* BitWriter.h */, 9FD3E58E0CA0125F00E54D15 /* Core.h */, CF8F1B490B64F7AB00BB4199 /* LinkTimeOptimizer.h */, ); - name = "llvm-c"; + name = "include/llvm-c"; path = "../include/llvm-c"; sourceTree = SOURCE_ROOT; }; @@ -1336,6 +1345,8 @@ 9F77937D0C73C4F400551F9C /* ConstantFold.h */, DE66EC6008ABE86A00323D32 /* Constants.cpp */, 9FD3E5900CA0129D00E54D15 /* Core.cpp */, + 9FE25D970CAB17F9005383FC /* DominatorCalculation.h */, + 9FE25D980CAB17F9005383FC /* DominatorInternals.cpp */, DE66EC6108ABE86A00323D32 /* Dominators.cpp */, DE66EC6208ABE86A00323D32 /* Function.cpp */, DE66EC6308ABE86A00323D32 /* Globals.cpp */, @@ -1374,6 +1385,7 @@ DE66ECBD08ABEC0700323D32 /* lib/Analysis */ = { isa = PBXGroup; children = ( + 9FE25D930CAB16D8005383FC /* PostDominatorCalculation.h */, 9F68EB010C77AD02004AA152 /* LoopPass.cpp */, 9F68EB020C77AD02004AA152 /* MemoryDependenceAnalysis.cpp */, DE66ED1A08ABEC0800323D32 /* IPA */, @@ -1447,6 +1459,7 @@ 9F7793550C73BD1500551F9C /* RegAllocBigBlock.cpp */, DE66ED8008ABEC2B00323D32 /* RegAllocLinearScan.cpp */, DE66ED8108ABEC2B00323D32 /* RegAllocLocal.cpp */, + 9FE25D940CAB16FB005383FC /* RegisterCoalescer.cpp */, 9F7793560C73BD1500551F9C /* RegisterScavenging.cpp */, DE66ED8208ABEC2B00323D32 /* RegAllocSimple.cpp */, 9F7793570C73BD1500551F9C /* SimpleRegisterCoalescing.cpp */, @@ -1543,6 +1556,7 @@ DE66EDFB08ABEDE600323D32 /* lib/Support */ = { isa = PBXGroup; children = ( + 9FE25D950CAB1724005383FC /* APFloat.cpp */, 9FE450A60C77AB3200C4FEA4 /* APInt.cpp */, 9FE450A70C77AB3200C4FEA4 /* ConstantRange.cpp */, 9FE450A80C77AB3200C4FEA4 /* MemoryBuffer.cpp */, @@ -1659,6 +1673,7 @@ CF9BCD1508C75070001E7011 /* SubtargetFeature.cpp */, DE66F08A08ABEE6000323D32 /* Target.td */, CF47BD860AAF487E00A8B13E /* TargetAsmInfo.cpp */, + 9FE25D960CAB1759005383FC /* TargetCallingConv.td */, DE66F08B08ABEE6000323D32 /* TargetData.cpp */, DE66F08C08ABEE6000323D32 /* TargetFrameInfo.cpp */, DE66F08D08ABEE6000323D32 /* TargetInstrInfo.cpp */, @@ -2116,6 +2131,7 @@ DE66F1F608ABF03100323D32 /* HashExtras.h */, DE66F1F708ABF03100323D32 /* ilist */, 9FA638E00C77B1AB007F12AE /* IndexedMap.h */, + 9FE25D900CAB166D005383FC /* APFloat.h */, 9FA638DB0C77B1AB007F12AE /* APInt.h */, 9FA638DC0C77B1AB007F12AE /* APSInt.h */, DE66F1F908ABF03100323D32 /* iterator.in */, @@ -2127,6 +2143,7 @@ 9FA638E30C77B1AB007F12AE /* SmallSet.h */, CF33BE160AF62B4200E93805 /* SmallString.h */, CF71B60F0AC45EDA0007F57C /* SmallVector.h */, + 9FE25D910CAB166D005383FC /* SparseBitVector.h */, 9FA638E40C77B1AB007F12AE /* StringMap.h */, DE66F1FE08ABF03100323D32 /* Statistic.h */, DE66F1FF08ABF03100323D32 /* STLExtras.h */, @@ -2211,6 +2228,7 @@ 9F7793890C73C57100551F9C /* MachORelocation.h */, DE66F24408ABF03100323D32 /* Passes.h */, CFE21C780A80CC0600D3E908 /* RegAllocRegistry.h */, + 9FE25D920CAB169F005383FC /* RegisterCoalescer.h */, 9F77938A0C73C57100551F9C /* RegisterScavenging.h */, CF8F1B410B64F6D100BB4199 /* RuntimeLibcalls.h */, DE66F24508ABF03100323D32 /* SchedGraphCommon.h */, From neil at daikokuya.co.uk Wed Sep 26 15:46:13 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Thu, 27 Sep 2007 07:46:13 +0900 Subject: [llvm-commits] [llvm] r42373 - /llvm/trunk/lib/Support/APFloat.cpp In-Reply-To: <0DAAAA07-62A3-4859-B95B-B6CDB1EE1679@apple.com> References: <200709262133.l8QLXgdx026535@zion.cs.uiuc.edu> <0DAAAA07-62A3-4859-B95B-B6CDB1EE1679@apple.com> Message-ID: <20070926224613.GL19035@daikokuya.co.uk> Dale Johannesen wrote:- > > > > APFloat::opStatus > > -APFloat::convertFromString(const char *p, roundingMode > > rounding_mode) { > > +APFloat::convertFromString(const char *p, roundingMode rounding_mode) > > +{ > > Most of llvm uses the K&R style here. I don't care though, do you > Chris? It seems you're right; I thought function bodies were different. Neil. From dalej at apple.com Wed Sep 26 16:20:33 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 26 Sep 2007 23:20:33 -0000 Subject: [llvm-commits] [llvm] r42383 - in /llvm/trunk/lib: Bitcode/Writer/BitcodeWriter.cpp CodeGen/AsmPrinter.cpp Target/CBackend/CBackend.cpp VMCore/AsmWriter.cpp Message-ID: <200709262320.l8QNKXKY030656@zion.cs.uiuc.edu> Author: johannes Date: Wed Sep 26 18:20:33 2007 New Revision: 42383 URL: http://llvm.org/viewvc/llvm-project?rev=42383&view=rev Log: Make temporaries explicit to avoid premature destruction of compiler-created ones. Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/CodeGen/AsmPrinter.cpp llvm/trunk/lib/Target/CBackend/CBackend.cpp llvm/trunk/lib/VMCore/AsmWriter.cpp Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=42383&r1=42382&r2=42383&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Wed Sep 26 18:20:33 2007 @@ -529,11 +529,14 @@ if (Ty == Type::FloatTy || Ty == Type::DoubleTy) { Record.push_back(CFP->getValueAPF().convertToAPInt().getZExtValue()); } else if (Ty == Type::X86_FP80Ty) { - const uint64_t *p = CFP->getValueAPF().convertToAPInt().getRawData(); + // api needed to prevent premature destruction + APInt api = CFP->getValueAPF().convertToAPInt(); + const uint64_t *p = api.getRawData(); Record.push_back(p[0]); Record.push_back((uint16_t)p[1]); } else if (Ty == Type::FP128Ty) { - const uint64_t *p = CFP->getValueAPF().convertToAPInt().getRawData(); + 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) { Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter.cpp?rev=42383&r1=42382&r2=42383&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Wed Sep 26 18:20:33 2007 @@ -876,7 +876,9 @@ return; } else if (CFP->getType() == Type::X86_FP80Ty) { // all long double variants are printed as hex - const uint64_t *p = CFP->getValueAPF().convertToAPInt().getRawData(); + // api needed to prevent premature destruction + APInt api = CFP->getValueAPF().convertToAPInt(); + const uint64_t *p = api.getRawData(); if (TD->isBigEndian()) { O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 48) << "\t" << TAI->getCommentString() Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=42383&r1=42382&r2=42383&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Wed Sep 26 18:20:33 2007 @@ -1729,7 +1729,9 @@ << " = 0x" << std::hex << i << std::dec << "U; /* " << Val << " */\n"; } else if (FPC->getType() == Type::X86_FP80Ty) { - const uint64_t *p = FPC->getValueAPF().convertToAPInt().getRawData(); + // api needed to prevent premature destruction + APInt api = FPC->getValueAPF().convertToAPInt(); + const uint64_t *p = api.getRawData(); Out << "static const ConstantFP80Ty FPConstant" << FPCounter++ << " = { 0x" << std::hex << ((uint16_t)p[1] | (p[0] & 0xffffffffffffLL)<<16) Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=42383&r1=42382&r2=42383&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original) +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Wed Sep 26 18:20:33 2007 @@ -521,7 +521,9 @@ Out << 'L'; else assert(0 && "Unsupported floating point type"); - const uint64_t* p = CFP->getValueAPF().convertToAPInt().getRawData(); + // api needed to prevent premature destruction + APInt api = CFP->getValueAPF().convertToAPInt(); + const uint64_t* p = api.getRawData(); uint64_t word = *p; int shiftcount=60; int width = CFP->getValueAPF().convertToAPInt().getBitWidth(); From dpatel at apple.com Wed Sep 26 16:41:43 2007 From: dpatel at apple.com (Devang Patel) Date: Wed, 26 Sep 2007 16:41:43 -0700 Subject: [llvm-commits] [llvm-gcc-4.0] r42353 - in /llvm-gcc-4.0/trunk/gcc: config/alpha/unicosmk.h config/darwin.h objc/objc-act.c In-Reply-To: <1190843035.11109.0.camel@asl.dorms.spbu.ru> References: <200709260906.l8Q960Pr001546@zion.cs.uiuc.edu> <4B72D5FA-1E0D-4A58-949F-51C00F58406E.SS832SS@apple.com> <1190843035.11109.0.camel@asl.dorms.spbu.ru> Message-ID: <6A2FF588-92CE-42EB-8751-A9F029C90DFD@apple.com> On Sep 26, 2007, at 2:43 PM, Anton Korobeynikov wrote: > Hello, Devang. > >> This breaks bootstrap on darwin. > Fixed! Please verify. Yup, its gone. Thanks! - Devang From evan.cheng at apple.com Wed Sep 26 17:25:29 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 27 Sep 2007 00:25:29 -0000 Subject: [llvm-commits] [llvm] r42384 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200709270025.l8R0PUUZ001293@zion.cs.uiuc.edu> Author: evancheng Date: Wed Sep 26 19:25:29 2007 New Revision: 42384 URL: http://llvm.org/viewvc/llvm-project?rev=42384&view=rev Log: Backtracking only when it won't create a cycle. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=42384&r1=42383&r2=42384&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Sep 26 19:25:29 2007 @@ -326,6 +326,40 @@ AvailableQueue->push(SU); } +// FIXME: This is probably too slow! +static void isReachable(SUnit *SU, SUnit *TargetSU, + SmallPtrSet &Visited, bool &Reached) { + if (Reached) return; + if (SU == TargetSU) { + Reached = true; + return; + } + if (!Visited.insert(SU)) return; + + for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; + ++I) + isReachable(I->Dep, TargetSU, Visited, Reached); +} + +static bool isReachable(SUnit *SU, SUnit *TargetSU) { + SmallPtrSet Visited; + bool Reached = false; + isReachable(SU, TargetSU, Visited, Reached); + return Reached; +} + +/// willCreateCycle - Returns true if adding an edge from SU to TargetSU will +/// create a cycle. +static bool willCreateCycle(SUnit *SU, SUnit *TargetSU) { + if (isReachable(TargetSU, SU)) + return true; + for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); + I != E; ++I) + if (I->Cost < 0 && isReachable(TargetSU, I->Dep)) + return true; + return false; +} + /// BacktrackBottomUp - Backtrack scheduling to a previous cycle specified in /// BTCycle in order to schedule a specific node. Returns the last unscheduled /// SUnit. Also returns if a successor is unscheduled in the process. @@ -469,28 +503,6 @@ return N->getValueType(NumRes); } -// FIXME: This is probably too slow! -static void isReachable(SUnit *SU, SUnit *TargetSU, - SmallPtrSet &Visited, bool &Reached) { - if (Reached) return; - if (SU == TargetSU) { - Reached = true; - return; - } - if (!Visited.insert(SU)) return; - - for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; - ++I) - isReachable(I->Dep, TargetSU, Visited, Reached); -} - -static bool isReachable(SUnit *SU, SUnit *TargetSU) { - SmallPtrSet Visited; - bool Reached = false; - isReachable(SU, TargetSU, Visited, Reached); - return Reached; -} - /// DelayForLiveRegsBottomUp - Returns true if it is necessary to delay /// scheduling of the given node to satisfy live physical register dependencies. /// If the specific node is the last one that's available to schedule, do @@ -547,7 +559,7 @@ } SUnit *OldSU = Sequence[LiveCycle]; - if (!isReachable(Sequence[LiveCycle], SU)) { + if (!willCreateCycle(SU, OldSU)) { // If CycleBound is greater than backtrack cycle, then some of SU // successors are going to be unscheduled. bool SuccUnsched = SU->CycleBound > LiveCycle; From gordonhenriksen at mac.com Wed Sep 26 19:47:27 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Thu, 27 Sep 2007 02:47:27 -0000 Subject: [llvm-commits] [llvm] r42385 - /llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c Message-ID: <200709270247.l8R2lRoq006692@zion.cs.uiuc.edu> Author: gordon Date: Wed Sep 26 21:47:27 2007 New Revision: 42385 URL: http://llvm.org/viewvc/llvm-project?rev=42385&view=rev Log: Remove debugging. 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=42385&r1=42384&r2=42385&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c Wed Sep 26 21:47:27 2007 @@ -21,8 +21,6 @@ #include "caml/mlvalues.h" #include "caml/memory.h" #include "llvm/Config/config.h" -#include -#include /*===-- Modules -----------------------------------------------------------===*/ @@ -477,7 +475,6 @@ #define Builder_val(v) (*(LLVMBuilderRef *)(Data_custom_val(v))) void llvm_finalize_builder(value B) { - fprintf(stderr, "disposing builder = 0x%08x\n", (int) Builder_val(B)); LLVMDisposeBuilder(Builder_val(B)); } @@ -505,7 +502,6 @@ value V; LLVMBuilderRef B = LLVMCreateBuilder(); LLVMPositionBuilderAtEnd(B, BB); - fprintf(stderr, "returning builder = 0x%08x\n", (int) B); V = alloc_custom(&builder_ops, sizeof(LLVMBuilderRef), 0, 1); Builder_val(V) = B; return V; From tonic at nondot.org Wed Sep 26 21:52:23 2007 From: tonic at nondot.org (Tanya Lattner) Date: Thu, 27 Sep 2007 04:52:23 -0000 Subject: [llvm-commits] [llvm] r42386 - /llvm/branches/release_21/docs/ReleaseNotes.html Message-ID: <200709270452.l8R4qNXr011207@zion.cs.uiuc.edu> Author: tbrethou Date: Wed Sep 26 23:52:22 2007 New Revision: 42386 URL: http://llvm.org/viewvc/llvm-project?rev=42386&view=rev Log: Merge release notes from mainline. Modified: llvm/branches/release_21/docs/ReleaseNotes.html Modified: llvm/branches/release_21/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_21/docs/ReleaseNotes.html?rev=42386&r1=42385&r2=42386&view=diff ============================================================================== --- llvm/branches/release_21/docs/ReleaseNotes.html (original) +++ llvm/branches/release_21/docs/ReleaseNotes.html Wed Sep 26 23:52:22 2007 @@ -4,11 +4,11 @@ - LLVM 2.0 Release Notes + LLVM 2.1 Release Notes -
            LLVM 2.0 Release Notes
            +
            LLVM 2.1 Release Notes
            1. Introduction
            2. @@ -32,7 +32,7 @@

              This document contains the release notes for the LLVM compiler -infrastructure, release 2.0. Here we describe the status of LLVM, including +infrastructure, release 2.1. Here we describe the status of LLVM, including major improvements from the previous release and any known problems. All LLVM releases may be downloaded from the LLVM releases web site.

              @@ -44,10 +44,9 @@ list is a good place to send them.

              Note that if you are reading this file from a Subversion checkout or the -main LLVM web page, -this document applies to the next release, not the current one. To see -the release notes for the current or previous releases, see the releases page.

              +main LLVM web page, this document applies to the next release, not the +current one. To see the release notes for a specific releases, please see the +releases page.

              @@ -59,416 +58,235 @@
              -

              This is the eleventh public release of the LLVM Compiler Infrastructure. -Being the first major release since 1.0, this release is different in several -ways from our previous releases:

              - -
                -
              1. We took this as an opportunity to -break backwards compatibility with the LLVM 1.x bytecode and .ll file format. -If you have LLVM 1.9 .ll files that you would like to upgrade to LLVM 2.x, we -recommend the use of the stand alone llvm-upgrade -tool (which is included with 2.0). We intend to keep compatibility with .ll -and .bc formats within the 2.x release series, like we did within the 1.x -series.
              2. -
              3. There are several significant change to the LLVM IR and internal APIs, such - as a major overhaul of the type system, the completely new bitcode file - format, etc (described below).
              4. -
              5. We designed the release around a 6 month release cycle instead of the usual - 3-month cycle. This gave us extra time to develop and test some of the - more invasive features in this release.
              6. -
              7. LLVM 2.0 no longer supports the llvm-gcc3 front-end. Users are required to - upgrade to llvm-gcc4. llvm-gcc4 includes many features over - llvm-gcc3, is faster, and is much easier to - build from source.
              8. -
              - -

              Note that while this is a major version bump, this release has been - extensively tested on a wide range of software. It is easy to say that this - is our best release yet, in terms of both features and correctness. This is - the first LLVM release to correctly compile and optimize major software like - LLVM itself, Mozilla/Seamonkey, Qt 4.3rc1, kOffice, etc out of the box on - linux/x86. -

              +

              This is the twelfth public release of the LLVM Compiler Infrastructure. +It includes many features and refinements from LLVM 2.0.

              - -
              -

              Changes to the LLVM IR itself:

              - -
                - -
              • Integer types are now completely signless. This means that we - have types like i8/i16/i32 instead of ubyte/sbyte/short/ushort/int - etc. LLVM operations that depend on sign have been split up into - separate instructions (PR950). This - eliminates cast instructions that just change the sign of the operands (e.g. - int -> uint), which reduces the size of the IR and makes optimizers - simpler to write.
              • +

                LLVM 2.1 brings two new beta C front-ends. First, a new version of llvm-gcc +based on GCC 4.2, innovatively called "llvm-gcc-4.2". This promises to bring +FORTRAN and Ada support to LLVM as well as features like atomic builtins and +OpenMP. None of these actually work yet, but don't let that stop you checking +it out!

                -
              • Integer types with arbitrary bitwidths (e.g. i13, i36, i42, i1057, etc) are - now supported in the LLVM IR and optimizations (PR1043). However, neither llvm-gcc - (PR1284) nor the native code generators - (PR1270) support non-standard width - integers yet.
              • +

                Second, LLVM now includes its own native C and Objective-C front-end (C++ is +in progress, but is not very far along) code named "clang". This front-end has a number of great +features, primarily aimed at source-level analysis and speeding up compile-time. +At this point though, the LLVM Code Generator component is still very early in +development, so it's mostly useful for people looking to build source-level +analysis tools or source-to-source translators.

                -
              • 'Type planes' have been removed (PR411). - It is no longer possible to have two values with the same name in the - same symbol table. This simplifies LLVM internals, allowing significant - speedups.
              • - -
              • Global variables and functions in .ll files are now prefixed with - @ instead of % (PR645).
              • +
              -
            3. The LLVM 1.x "bytecode" format has been replaced with a - completely new binary representation, named 'bitcode'. The Bitcode Format brings a - number of advantages to the LLVM over the old bytecode format: it is denser - (files are smaller), more extensible, requires less memory to read, - is easier to keep backwards compatible (so LLVM 2.5 will read 2.0 .bc - files), and has many other nice features.
            4. + + -
            5. Load and store instructions now track the alignment of their pointer - (PR400). This allows the IR to - express loads that are not sufficiently aligned (e.g. due to '#pragma - packed') or to capture extra alignment information.
            6. -
          +
          -

          Major new features:

          +

          Some of the most noticable feature improvements this release have been in the +optimizer, speeding it up and making it more aggressive. For example:

            -
          • A number of ELF features are now supported by LLVM, including 'visibility', - extern weak linkage, Thread Local Storage (TLS) with the __thread - keyword, and symbol aliases. - Among other things, this means that many of the special options needed to - configure llvm-gcc on linux are no longer needed, and special hacks to build - large C++ libraries like Qt are not needed.
          • +
          • Owen Anderson wrote the new MemoryDependenceAnalysis pass, which provides + a lazy, caching layer on top of AliasAnalysis. He then used it to rewrite + DeadStoreElimination which resulted in significantly better compile time in + common cases,
          • +
          • Owen implemented the new GVN pass, which is also based on + MemoryDependenceAnalysis. This pass replaces GCSE/LoadVN in the standard + set of passes, providing more aggressive optimization at a some-what + improved compile-time cost.
          • +
          • Owen implemented GVN-PRE, a partial redundancy elimination algorithm that + shares some details with the new GVN pass. It is still in need of compile + time tuning, and is not turned on by default.
          • +
          • Devang merged ETForest and DomTree into a single easier to use data + structure. This makes it more obvious which datastructure to choose + (because there is only one) and makes the compiler more memory and time + efficient (less stuff to keep up-to-date).
          • +
          • Nick Lewycky improved loop trip count analysis to handle many more common + cases.
          • -
          • LLVM now has a new MSIL backend. llc -march=msil will now turn LLVM - into MSIL (".net") bytecode. This is still fairly early development - with a number of limitations.
          • - -
          • A new llvm-upgrade tool - exists to migrates LLVM 1.9 .ll files to LLVM 2.0 syntax.
          - - - -
          -

          New features include: -

          - -
            -
          • Precompiled Headers (PCH) are now supported.
          • - -
          • "#pragma packed" is now supported, as are the various features - described above (visibility, extern weak linkage, __thread, aliases, - etc).
          • - -
          • Tracking function parameter/result attributes is now possible.
          • - -
          • Many internal enhancements have been added, such as improvements to - NON_LVALUE_EXPR, arrays with non-zero base, structs with variable sized - fields, VIEW_CONVERT_EXPR, CEIL_DIV_EXPR, nested functions, and many other - things. This is primarily to supports non-C GCC front-ends, like Ada.
          • - -
          • It is simpler to configure llvm-gcc for linux.
          • - -
          - + + - - -
          -

          New features include: -

          - -
            -
          • The pass manager has been entirely - rewritten, making it significantly smaller, simpler, and more extensible. - Support has been added to run FunctionPasses interlaced with - CallGraphSCCPasses, we now support loop transformations - explicitly with LoopPass, and ModulePasses may now use the - result of FunctionPasses.
          • - -
          • LLVM 2.0 includes a new loop rotation pass, which converts "for loops" into - "do/while loops", where the condition is at the bottom of the loop.
          • - -
          • The Loop Strength Reduction pass has been improved, and we now support - sinking expressions across blocks to reduce register pressure.
          • - -
          • The -scalarrepl pass can now promote unions containing FP values - into a register, it can also handle unions of vectors of the same - size.
          • - -
          • The [Post]DominatorSet classes have been removed from LLVM and clients - switched to use the more-efficient ETForest class instead.
          • - -
          • The ImmediateDominator class has also been removed, and clients have been - switched to use DominatorTree instead.
          • - -
          • The predicate simplifier pass has been improved, making it able to do - simple value range propagation and eliminate more conditionals. However, - note that predsimplify is not enabled by default in llvm-gcc.
          • -
          - -
          - - - - -
          -

          -New features include: -

          +

          One of the main focuses of this release was performance tuning and bug + fixing. In addition to these, several new major changes occurred:

            -
          • LLVM now supports software floating point, which allows LLVM to target - chips that don't have hardware FPUs (e.g. ARM thumb mode).
          • - -
          • A new register scavenger has been implemented, which is useful for - finding free registers after register allocation. This is useful when - rewriting frame references on RISC targets, for example.
          • +
          • Dale finished up the Tail Merging optimization in the code generator, and + enabled it by default. This produces smaller code that is also faster in + some cases.
          • -
          • Heuristics have been added to avoid coalescing vregs with very large live - ranges to physregs. This was bad because it effectively pinned the physical - register for the entire lifetime of the virtual register (PR711).
          • +
          • Christopher Lamb implemented support for virtual register sub-registers, + which can be used to better model many forms of subregisters. As an example + use, he modified the X86 backend to use this to model truncates and + extends more accurately (leading to better code).
          • -
          • Support now exists for very simple (but still very useful) - rematerialization the register allocator, enough to move - instructions like "load immediate" and constant pool loads.
          • +
          • Dan Gohman changed the way we represent vectors before legalization, + significantly simplifying the SelectionDAG representation for these and + making the code generator faster for vector code.
          • -
          • Switch statement lowering is significantly better, improving codegen for - sparse switches that have dense subregions, and implemented support - for the shift/and trick.
          • +
          • Evan contributed a new target independent if-converter. While it is + target independent, so far only the ARM backend uses it.
          • -
          • LLVM now supports tracking physreg sub-registers and super-registers - in the code generator, and includes extensive register - allocator changes to track them.
          • +
          • Evan rewrite the way the register allocator handles rematerialization, + allowing it to be much more effective on two-address targets like X86, + and taught it to fold loads away when possible (also a big win on X86).
          • -
          • There is initial support for virtreg sub-registers - (PR1350).
          • - -
          +
        5. Dan Gohman contributed support for better alignment and volatility handling + in the code generator, and significantly enhanced alignment analysis for SSE + load/store instructions. With his changes, an insufficiently-aligned SSE + load instruction turns into movups, for example.
        6. -

          -Other improvements include: -

          - -
            +
          • Duraid Madina contributed a new "bigblock" register allocator, and Roman + Levenstein contributed several big improvements. BigBlock is optimized for + code that uses very large basic blocks. It is slightly slower than the + "local" allocator, but produces much better code.
          • -
          • Inline assembly support is much more solid that before. - The two primary features still missing are support for 80-bit floating point - stack registers on X86 (PR879), and - support for inline asm in the C backend (PR802).
          • - -
          • DWARF debug information generation has been improved. LLVM now passes - most of the GDB testsuite on MacOS and debug info is more dense.
          • - -
          • Codegen support for Zero-cost DWARF exception handling has been added (PR592). It is mostly - complete and just in need of continued bug fixes and optimizations at - this point. However, support in llvm-g++ is disabled with an - #ifdef for the 2.0 release (PR870).
          • - -
          • The code generator now has more accurate and general hooks for - describing addressing modes ("isLegalAddressingMode") to - optimizations like loop strength reduction and code sinking.
          • - -
          • Progress has been made on a direct Mach-o .o file writer. Many small - apps work, but it is still not quite complete.
          • +
          • David Greene refactored the register allocator to split coalescing out from + allocation, making coalescers pluggable.
          -

          In addition, the LLVM target description format has itself been extended in - several ways:

          - -
            -
          • TargetData now supports better target parameterization in - the .ll/.bc files, eliminating the 'pointersize/endianness' attributes - in the files (PR761).
          • - -
          • TargetData was generalized for finer grained alignment handling, - handling of vector alignment, and handling of preferred alignment
          • - -
          • LLVM now supports describing target calling conventions - explicitly in .td files, reducing the amount of C++ code that needs - to be written for a port.
          • +
  • -
+ + - - -
- -

X86-specific Code Generator Enhancements: +

New features include:

    -
  • The MMX instruction set is now supported through intrinsics.
  • -
  • The scheduler was improved to better reduce register pressure on - X86 and other targets that are register pressure sensitive.
  • -
  • Linux/x86-64 support is much better.
  • -
  • PIC support for linux/x86 has been added.
  • -
  • The X86 backend now supports the GCC regparm attribute.
  • -
  • LLVM now supports inline asm with multiple constraint letters per operand - (like "mri") which is common in X86 inline asms.
  • -
- -

ARM-specific Code Generator Enhancements:

- -
    -
  • The ARM code generator is now stable and fully supported.
  • - -
  • There are major new features, including support for ARM - v4-v6 chips, vfp support, soft float point support, pre/postinc support, - load/store multiple generation, constant pool entry motion (to support - large functions), inline asm support, weak linkage support, static - ctor/dtor support and many bug fixes.
  • +
  • Bruno Cardoso Lopes contributed initial MIPS support. It is sufficient to + run many small programs, but is still incomplete and is not yet + fully performant.
  • -
  • Added support for Thumb code generation (llc -march=thumb).
  • +
  • Bill Wendling added SSSE3 support to the X86 backend.
  • -
  • The ARM backend now supports the ARM AAPCS/EABI ABI and PIC codegen on - arm/linux.
  • +
  • Nicholas Geoffray contributed improved linux/ppc ABI and JIT support.
  • -
  • Several bugs were fixed for DWARF debug info generation on arm/linux.
  • +
  • Dale Johannesen rewrote handling of 32-bit float values in the X86 backend + when using the floating point stack, fixing several nasty bugs.
  • +
  • Dan contributed rematerialization support for the X86 backend, in addition + to several X86-specific micro optimizations.
+ +
-

PowerPC-specific Code Generator Enhancements:

- -
    -
  • The PowerPC 64 JIT now supports addressing code loaded above the 2G - boundary.
  • - -
  • Improved support for the Linux/ppc ABI and the linux/ppc JIT is fully - functional now. llvm-gcc and static compilation are not fully supported - yet though.
  • - -
  • Many PowerPC 64 bug fixes.
  • - -
+ + - - -
- -

More specific changes include:

+

New features include: +

    -
  • LLVM no longer relies on static destructors to shut itself down. Instead, - it lazily initializes itself and shuts down when llvm_shutdown() is - explicitly called.
  • - -
  • LLVM now has significantly fewer static constructors, reducing startup time. -
  • - -
  • Several classes have been refactored to reduce the amount of code that - gets linked into apps that use the JIT.
  • - -
  • Construction of intrinsic function declarations has been simplified.
  • - -
  • The gccas/gccld tools have been replaced with small shell scripts.
  • +
  • Duncan and Anton made significant progress chasing down a number of problems + with C++ Zero-Cost exception handling in llvm-gcc 4.0 and 4.2. It is now at + the point where it "just works" on linux/X86-32 and has partial support on + other targets.
  • + +
  • Devang and Duncan fixed a huge number of bugs relating to bitfields, pragma + pack, and variable sized fields in structures.
  • + +
  • Tanya implemented support for __attribute__((noinline)) in + llvm-gcc, and added support for generic variable annotations which are + propagated into the LLVM IR, e.g. + "int X __attribute__((annotate("myproperty")));".
  • + +
  • Sheng Zhou and Christopher Lamb implemented alias analysis support for +"restrict" pointer arguments to functions.
  • + +
  • Duncan contributed support for trampolines (taking the address of a nested + function). Currently this is only supported on the X86-32 target.
  • + +
  • Lauro Ramos Venancio contributed support to encode alignment info in + load and store instructions, the foundation for other alignment-related + work.
  • +
+ +
-
  • Support has been added to llvm-test for running on low-memory - or slow machines (make SMALL_PROBLEM_SIZE=1).
  • - + + - -
    - -

    LLVM 2.0 contains a revamp of the type system and several other significant -internal changes. If you are programming to the C++ API, be aware of the -following major changes:

    +

    New features include: +

      -
    • Pass registration is slightly different in LLVM 2.0 (you now need an - intptr_t in your constructor), as explained in the Writing an LLVM Pass - document.
    • - -
    • ConstantBool, ConstantIntegral and ConstantInt - classes have been merged together, we now just have - ConstantInt.
    • - -
    • Type::IntTy, Type::UIntTy, Type::SByteTy, ... are - replaced by Type::Int8Ty, Type::Int16Ty, etc. LLVM types - have always corresponded to fixed size types - (e.g. long was always 64-bits), but the type system no longer includes - information about the sign of the type. Also, the - Type::isPrimitiveType() method now returns false for integers.
    • - -
    • Several classes (CallInst, GetElementPtrInst, - ConstantArray, etc), that once took std::vector as - arguments now take ranges instead. For example, you can create a - GetElementPtrInst with code like: +
    • Neil Booth contributed a new "APFloat" class, which ensures that floating + point representation and constant folding is not dependent on the host + architecture that builds the application. This support is the foundation + for "long double" support that will be wrapped up in LLVM 2.2.
    • -
      -      Value *Ops[] = { Op1, Op2, Op3 };
      -      GEP = new GetElementPtrInst(BasePtr, Ops, 3);
      -    
      - - This avoids creation of a temporary vector (and a call to malloc/free). If - you have an std::vector, use code like this: -
      -      std::vector<Value*> Ops = ...;
      -      GEP = new GetElementPtrInst(BasePtr, &Ops[0], Ops.size());
      -    
      +
    • Based on the APFloat class, Dale redesigned the internals of the ConstantFP + class and has been working on extending the core and optimizer components to + support various target-specific 'long double's. We expect this work to be + completed in LLVM 2.2.
    • + +
    • LLVM now provides an LLVMBuilder class, which makes it significantly easier + to create LLVM IR instructions.
    • + +
    • Reid contributed support for intrinsics that take arbitrary integer typed + arguments. Dan Gohman and Chandler extended it to support arbitrary + floating point arguments and vectors.
    • +
    + +
    - - -
  • CastInst is now abstract and its functionality is split into - several parts, one for each of the new - cast instructions.
  • - -
  • Instruction::getNext()/getPrev() are now private (along with - BasicBlock::getNext, etc), for efficiency reasons (they are now no - longer just simple pointers). Please use BasicBlock::iterator, etc - instead. -
  • + + -
  • Module::getNamedFunction() is now called - Module::getFunction().
  • +
    +

    New features include: +

    -
  • SymbolTable.h has been split into ValueSymbolTable.h and -TypeSymbolTable.h.
  • +
      +
    • Sterling Stein contributed a new BrainF frontend, located in llvm/examples. + This shows a some of the more modern APIs for building a front-end, and + demonstrates JIT compiler support.
    • + +
    • David Green contributed a new --enable-expensive-checks configure + option which enables STL checking, and fixed several bugs exposed by + it.
    +
    -
    Portability and Supported Platforms @@ -530,12 +348,11 @@ components, please contact us on the LLVMdev list.

      -
    • The -cee pass is known to be buggy, and may be removed in in a +
    • The -cee pass is known to be buggy, and may be removed in a future release.
    • -
    • C++ EH support is disabled for this release.
    • The MSIL backend is experimental.
    • The IA64 code generator is experimental.
    • -
    • The Alpha JIT is experimental.
    • +
    • The Alpha backend is experimental.
    • "-filetype=asm" (the default) is the only supported value for the -filetype llc option.
    @@ -552,6 +369,9 @@
    @@ -581,7 +401,7 @@