From sabre at nondot.org Mon Oct 15 00:30:28 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 15 Oct 2007 05:30:28 -0000
Subject: [llvm-commits] [llvm] r42976 -
/llvm/trunk/include/llvm/Target/TargetLowering.h
Message-ID: <200710150530.l9F5USJ9028995@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Oct 15 00:30:27 2007
New Revision: 42976
URL: http://llvm.org/viewvc/llvm-project?rev=42976&view=rev
Log:
Fix 80 col violation
Modified:
llvm/trunk/include/llvm/Target/TargetLowering.h
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=42976&r1=42975&r2=42976&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Mon Oct 15 00:30:27 2007
@@ -538,9 +538,9 @@
}
/// ShrinkDemandedConstant - Check to see if the specified operand of the
- /// specified instruction is a constant integer. If so, check to see if there
- /// are any bits set in the constant that are not demanded. If so, shrink the
- /// constant and return true.
+ /// specified instruction is a constant integer. If so, check to see if
+ /// there are any bits set in the constant that are not demanded. If so,
+ /// shrink the constant and return true.
bool ShrinkDemandedConstant(SDOperand Op, uint64_t Demanded);
};
From sabre at nondot.org Mon Oct 15 00:30:55 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 15 Oct 2007 05:30:55 -0000
Subject: [llvm-commits] [llvm] r42977 -
/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
Message-ID: <200710150530.l9F5UunS029021@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Oct 15 00:30:55 2007
New Revision: 42977
URL: http://llvm.org/viewvc/llvm-project?rev=42977&view=rev
Log:
remove dead enum, make setNodeId public.
Modified:
llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=42977&r1=42976&r2=42977&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Mon Oct 15 00:30:55 2007
@@ -419,13 +419,6 @@
// indexed memory ops).
LOAD, STORE,
- // TRUNCSTORE - This operators truncates (for integer) or rounds (for FP) a
- // value and stores it to memory in one operation. This can be used for
- // either integer or floating point operands. The first four operands of
- // this are the same as a standard store. The fifth is the ValueType to
- // store it as (which will be smaller than the source value).
- TRUNCSTORE,
-
// DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned
// to a specified boundary. This node always has two return values: a new
// stack pointer value and a chain. The first operand is the token chain,
@@ -950,6 +943,10 @@
///
void Profile(FoldingSetNodeID &ID);
+ void setNodeId(int Id) {
+ NodeId = Id;
+ }
+
protected:
friend class SelectionDAG;
@@ -1018,10 +1015,6 @@
}
}
}
-
- void setNodeId(int Id) {
- NodeId = Id;
- }
};
From sabre at nondot.org Mon Oct 15 00:32:43 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 15 Oct 2007 05:32:43 -0000
Subject: [llvm-commits] [llvm] r42978 -
/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
Message-ID: <200710150532.l9F5Wh6Q029071@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Oct 15 00:32:43 2007
New Revision: 42978
URL: http://llvm.org/viewvc/llvm-project?rev=42978&view=rev
Log:
Add a (disabled by default) way to view the ID of a node.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp?rev=42978&r1=42977&r2=42978&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Mon Oct 15 00:32:43 2007
@@ -172,6 +172,10 @@
Op = Op + "getStoredVT()) + ">";
Op += ST->getIndexedModeName(ST->getAddressingMode());
}
+
+#if 0
+ Op += " Id=" + itostr(Node->getNodeId());
+#endif
return Op;
}
From sabre at nondot.org Mon Oct 15 00:34:10 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 15 Oct 2007 05:34:10 -0000
Subject: [llvm-commits] [llvm] r42979 -
/llvm/trunk/lib/VMCore/ConstantFold.cpp
Message-ID: <200710150534.l9F5YA97029115@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Oct 15 00:34:10 2007
New Revision: 42979
URL: http://llvm.org/viewvc/llvm-project?rev=42979&view=rev
Log:
avoid an APFloat copy.
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=42979&r1=42978&r2=42979&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/ConstantFold.cpp (original)
+++ llvm/trunk/lib/VMCore/ConstantFold.cpp Mon Oct 15 00:34:10 2007
@@ -194,7 +194,7 @@
case Instruction::FPToUI:
case Instruction::FPToSI:
if (const ConstantFP *FPC = dyn_cast(V)) {
- APFloat V = FPC->getValueAPF();
+ const APFloat &V = FPC->getValueAPF();
uint64_t x[2];
uint32_t DestBitWidth = cast(DestTy)->getBitWidth();
(void) V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI,
From sabre at nondot.org Mon Oct 15 00:46:06 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 15 Oct 2007 05:46:06 -0000
Subject: [llvm-commits] [llvm] r42980 -
/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Message-ID: <200710150546.l9F5k6g1029578@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Oct 15 00:46:06 2007
New Revision: 42980
URL: http://llvm.org/viewvc/llvm-project?rev=42980&view=rev
Log:
One xform performed by LegalizeDAG is transformation of "store of fp" to "store of int".
Make two changes:
1) only xform "store of f32" if i32 is a legal type for the target.
2) only xform "store of f64" if either i64 or i32 are legal for the target.
3) if i64 isn't legal, manually lower to 2 stores of i32 instead of letting a
later pass of legalize do it. This is ugly, but helps future changes I'm
about to commit.
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=42980&r1=42979&r2=42980&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Oct 15 00:46:06 2007
@@ -2026,7 +2026,8 @@
// together.
// We generally can't do this one for long doubles.
if (ConstantFPSDNode *CFP = dyn_cast(ST->getValue())) {
- if (CFP->getValueType(0) == MVT::f32) {
+ if (CFP->getValueType(0) == MVT::f32 &&
+ getTypeAction(MVT::i32) == Legal) {
Tmp3 = DAG.getConstant((uint32_t)CFP->getValueAPF().
convertToAPInt().getZExtValue(),
MVT::i32);
@@ -2034,11 +2035,32 @@
SVOffset, isVolatile, Alignment);
break;
} else if (CFP->getValueType(0) == MVT::f64) {
- Tmp3 = DAG.getConstant(CFP->getValueAPF().convertToAPInt().
- getZExtValue(), MVT::i64);
- Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
- break;
+ // If this target supports 64-bit registers, do a single 64-bit store.
+ if (getTypeAction(MVT::i64) == Legal) {
+ Tmp3 = DAG.getConstant(CFP->getValueAPF().convertToAPInt().
+ getZExtValue(), MVT::i64);
+ Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ SVOffset, isVolatile, Alignment);
+ break;
+ } else if (getTypeAction(MVT::i32) == Legal) {
+ // Otherwise, if the target supports 32-bit registers, use 2 32-bit
+ // stores. If the target supports neither 32- nor 64-bits, this
+ // xform is certainly not worth it.
+ uint64_t IntVal =CFP->getValueAPF().convertToAPInt().getZExtValue();
+ SDOperand Lo = DAG.getConstant(uint32_t(IntVal), MVT::i32);
+ SDOperand Hi = DAG.getConstant(uint32_t(IntVal >>32), MVT::i32);
+ if (!TLI.isLittleEndian()) std::swap(Lo, Hi);
+
+ Lo = DAG.getStore(Tmp1, Lo, Tmp2, ST->getSrcValue(),
+ SVOffset, isVolatile, Alignment);
+ Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+ getIntPtrConstant(4));
+ Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset+4,
+ isVolatile, std::max(Alignment, 4U));
+
+ Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+ break;
+ }
}
}
From sabre at nondot.org Mon Oct 15 01:10:22 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 15 Oct 2007 06:10:22 -0000
Subject: [llvm-commits] [llvm] r42981 - in /llvm/trunk:
include/llvm/CodeGen/SelectionDAG.h
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
utils/TableGen/DAGISelEmitter.cpp
Message-ID: <200710150610.l9F6ANV3030436@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Oct 15 01:10:22 2007
New Revision: 42981
URL: http://llvm.org/viewvc/llvm-project?rev=42981&view=rev
Log:
One mundane change: Change ReplaceAllUsesOfValueWith to *optionally*
take a deleted nodes vector, instead of requiring it.
One more significant change: Implement the start of a legalizer that
just works on types. This legalizer is designed to run before the
operation legalizer and ensure just that the input dag is transformed
into an output dag whose operand and result types are all legal, even
if the operations on those types are not.
This design/impl has the following advantages:
1. When finished, this will *significantly* reduce the amount of code in
LegalizeDAG.cpp. It will remove all the code related to promotion and
expansion as well as splitting and scalarizing vectors.
2. The new code is very simple, idiomatic, and modular: unlike
LegalizeDAG.cpp, it has no 3000 line long functions. :)
3. The implementation is completely iterative instead of recursive, good
for hacking on large dags without blowing out your stack.
4. The implementation updates nodes in place when possible instead of
deallocating and reallocating the entire graph that points to some
mutated node.
5. The code nicely separates out handling of operations with invalid
results from operations with invalid operands, making some cases
simpler and easier to understand.
6. The new -debug-only=legalize-types option is very very handy :),
allowing you to easily understand what legalize types is doing.
This is not yet done. Until the ifdef added to SelectionDAGISel.cpp is
enabled, this does nothing. However, this code is sufficient to legalize
all of the code in 186.crafty, olden and freebench on an x86 machine. The
biggest issues are:
1. Vectors aren't implemented at all yet
2. SoftFP is a mess, I need to talk to Evan about it.
3. No lowering to libcalls is implemented yet.
4. Various operations are missing etc.
5. There are FIXME's for stuff I hax0r'd out, like softfp.
Hey, at least it is a step in the right direction :). If you'd like to help,
just enable the #ifdef in SelectionDAGISel.cpp and compile code with it. If
this explodes it will tell you what needs to be implemented. Help is
certainly appreciated.
Once this goes in, we can do three things:
1. Add a new pass of dag combine between the "type legalizer" and "operation
legalizer" passes. This will let us catch some long-standing isel issues
that we miss because operation legalization often obfuscates the dag with
target-specific nodes.
2. We can rip out all of the type legalization code from LegalizeDAG.cpp,
making it much smaller and simpler. When that happens we can then
reimplement the core functionality left in it in a much more efficient and
non-recursive way.
3. Once the whole legalizer is non-recursive, we can implement whole-function
selectiondags maybe...
Added:
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
Modified:
llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=42981&r1=42980&r2=42981&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Mon Oct 15 01:10:22 2007
@@ -120,6 +120,13 @@
/// generate any nodes that will be illegal on the target.
void Combine(bool AfterLegalize, AliasAnalysis &AA);
+ /// LegalizeTypes - This transforms the SelectionDAG into a SelectionDAG that
+ /// only uses types natively supported by the target.
+ ///
+ /// Note that this is an involved process that may invalidate pointers into
+ /// the graph.
+ void LegalizeTypes();
+
/// Legalize - This transforms the SelectionDAG into a SelectionDAG that is
/// compatible with the target instruction selector, as indicated by the
/// TargetLowering object.
@@ -451,7 +458,7 @@
/// handled the same was as for ReplaceAllUsesWith, but it is required for
/// this method.
void ReplaceAllUsesOfValueWith(SDOperand From, SDOperand To,
- std::vector &Deleted);
+ std::vector *Deleted = 0);
/// AssignNodeIds - Assign a unique node id for each node in the DAG based on
/// their allnodes order. It returns the maximum id.
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=42981&r1=42980&r2=42981&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Oct 15 01:10:22 2007
@@ -173,7 +173,7 @@
DOUT << '\n';
std::vector NowDead;
- DAG.ReplaceAllUsesOfValueWith(TLO.Old, TLO.New, NowDead);
+ DAG.ReplaceAllUsesOfValueWith(TLO.Old, TLO.New, &NowDead);
// Push the new node and any (possibly new) users onto the worklist.
AddToWorkList(TLO.New.Val);
@@ -1414,8 +1414,6 @@
///
bool DAGCombiner::SimplifyNodeWithTwoResults(SDNode *N,
unsigned LoOp, unsigned HiOp) {
- std::vector NowDead;
-
// If the high half is not needed, just compute the low half.
if (!N->hasAnyUseOfValue(1) &&
(!AfterLegalize ||
@@ -1423,8 +1421,7 @@
DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0),
DAG.getNode(LoOp, N->getValueType(0),
N->op_begin(),
- N->getNumOperands()),
- NowDead);
+ N->getNumOperands()));
return true;
}
@@ -1435,8 +1432,7 @@
DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1),
DAG.getNode(HiOp, N->getValueType(1),
N->op_begin(),
- N->getNumOperands()),
- NowDead);
+ N->getNumOperands()));
return true;
}
@@ -1464,8 +1460,8 @@
(HiExists || HiOpt != Hi) &&
TLI.isOperationLegal(LoOpt.getOpcode(), LoOpt.getValueType()) &&
TLI.isOperationLegal(HiOpt.getOpcode(), HiOpt.getValueType())) {
- DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), LoOpt, NowDead);
- DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), HiOpt, NowDead);
+ DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), LoOpt);
+ DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), HiOpt);
return true;
}
@@ -2891,8 +2887,7 @@
LN0->isVolatile(), LN0->getAlignment());
AddToWorkList(N);
if (CombineSRL) {
- std::vector NowDead;
- DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1), NowDead);
+ DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1));
CombineTo(N->getOperand(0).Val, Load);
} else
CombineTo(N0.Val, Load, Load.getValue(1));
@@ -3694,12 +3689,12 @@
std::vector NowDead;
if (isLoad) {
DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
- NowDead);
+ &NowDead);
DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
- NowDead);
+ &NowDead);
} else {
DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
- NowDead);
+ &NowDead);
}
// Nodes can end up on the worklist more than once. Make sure we do
@@ -3711,7 +3706,7 @@
// Replace the uses of Ptr with uses of the updated base value.
DAG.ReplaceAllUsesOfValueWith(Ptr, Result.getValue(isLoad ? 1 : 0),
- NowDead);
+ &NowDead);
removeFromWorkList(Ptr.Val);
for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
removeFromWorkList(NowDead[i]);
@@ -3825,12 +3820,12 @@
std::vector NowDead;
if (isLoad) {
DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
- NowDead);
+ &NowDead);
DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
- NowDead);
+ &NowDead);
} else {
DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
- NowDead);
+ &NowDead);
}
// Nodes can end up on the worklist more than once. Make sure we do
@@ -3843,7 +3838,7 @@
// Replace the uses of Use with uses of the updated base value.
DAG.ReplaceAllUsesOfValueWith(SDOperand(Op, 0),
Result.getValue(isLoad ? 1 : 0),
- NowDead);
+ &NowDead);
removeFromWorkList(Op);
for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
removeFromWorkList(NowDead[i]);
Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=42981&view=auto
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (added)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Mon Oct 15 01:10:22 2007
@@ -0,0 +1,1522 @@
+//===-- LegalizeDAGTypes.cpp - Implement SelectionDAG::LegalizeTypes ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SelectionDAG::LegalizeTypes method. It transforms
+// an arbitrary well-formed SelectionDAG to only consist of legal types.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "legalize-types"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+/// DAGTypeLegalizer - This takes an arbitrary SelectionDAG as input and
+/// hacks on it until the target machine can handle it. This involves
+/// eliminating value sizes the machine cannot handle (promoting small sizes to
+/// large sizes or splitting up large values into small values) as well as
+/// eliminating operations the machine cannot handle.
+///
+/// This code also does a small amount of optimization and recognition of idioms
+/// as part of its processing. For example, if a target does not support a
+/// 'setcc' instruction efficiently, but does support 'brcc' instruction, this
+/// will attempt merge setcc and brc instructions into brcc's.
+///
+namespace {
+class VISIBILITY_HIDDEN DAGTypeLegalizer {
+ TargetLowering &TLI;
+ SelectionDAG &DAG;
+
+ // NodeIDFlags - This pass uses the NodeID on the SDNodes to hold information
+ // about the state of the node. The enum has all the values.
+ enum NodeIDFlags {
+ /// ReadyToProcess - All operands have been processed, so this node is ready
+ /// to be handled.
+ ReadyToProcess = 0,
+
+ /// NewNode - This is a new node that was created in the process of
+ /// legalizing some other node.
+ NewNode = -1,
+
+ /// Processed - This is a node that has already been processed.
+ Processed = -2
+
+ // 1+ - This is a node which has this many unlegalized operands.
+ };
+
+ enum LegalizeAction {
+ Legal, // The target natively supports this operation.
+ Promote, // This operation should be executed in a larger type.
+ Expand // Try to expand this to other ops, otherwise use a libcall.
+ };
+
+ /// ValueTypeActions - This is a bitvector that contains two bits for each
+ /// value type, where the two bits correspond to the LegalizeAction enum.
+ /// This can be queried with "getTypeAction(VT)".
+ TargetLowering::ValueTypeActionImpl ValueTypeActions;
+
+ /// getTypeAction - Return how we should legalize values of this type, either
+ /// it is already legal or we need to expand it into multiple registers of
+ /// smaller integer type, or we need to promote it to a larger type.
+ LegalizeAction getTypeAction(MVT::ValueType VT) const {
+ return (LegalizeAction)ValueTypeActions.getTypeAction(VT);
+ }
+
+ /// isTypeLegal - Return true if this type is legal on this target.
+ ///
+ bool isTypeLegal(MVT::ValueType VT) const {
+ return getTypeAction(VT) == Legal;
+ }
+
+ SDOperand getIntPtrConstant(uint64_t Val) {
+ return DAG.getConstant(Val, TLI.getPointerTy());
+ }
+
+ /// PromotedNodes - For nodes that are below legal width, and that have more
+ /// than one use, this map indicates what promoted value to use.
+ DenseMap PromotedNodes;
+
+ /// ExpandedNodes - For nodes that need to be expanded this map indicates
+ /// which which operands are the expanded version of the input.
+ DenseMap > ExpandedNodes;
+
+ /// Worklist - This defines a worklist of nodes to process. In order to be
+ /// pushed onto this worklist, all operands of a node must have already been
+ /// processed.
+ SmallVector Worklist;
+
+public:
+ DAGTypeLegalizer(SelectionDAG &dag)
+ : TLI(dag.getTargetLoweringInfo()), DAG(dag),
+ ValueTypeActions(TLI.getValueTypeActions()) {
+ assert(MVT::LAST_VALUETYPE <= 32 &&
+ "Too many value types for ValueTypeActions to hold!");
+ }
+
+ void run();
+
+private:
+ void MarkNewNodes(SDNode *N);
+
+ void ReplaceLegalValueWith(SDOperand From, SDOperand To);
+
+ SDOperand GetPromotedOp(SDOperand Op) {
+ Op = PromotedNodes[Op];
+ assert(Op.Val && "Operand wasn't promoted?");
+ return Op;
+ }
+ void SetPromotedOp(SDOperand Op, SDOperand Result);
+
+ void GetExpandedOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
+ void SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi);
+
+ // Result Promotion.
+ void PromoteResult(SDNode *N, unsigned ResNo);
+ SDOperand PromoteResult_UNDEF(SDNode *N);
+ SDOperand PromoteResult_Constant(SDNode *N);
+ SDOperand PromoteResult_TRUNCATE(SDNode *N);
+ SDOperand PromoteResult_INT_EXTEND(SDNode *N);
+ SDOperand PromoteResult_FP_ROUND(SDNode *N);
+ SDOperand PromoteResult_SETCC(SDNode *N);
+ SDOperand PromoteResult_LOAD(LoadSDNode *N);
+ SDOperand PromoteResult_SimpleIntBinOp(SDNode *N);
+
+ // Result Expansion.
+ void ExpandResult(SDNode *N, unsigned ResNo);
+ void ExpandResult_UNDEF (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandResult_Constant (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandResult_BUILD_PAIR (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandResult_ANY_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandResult_ZERO_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandResult_SIGN_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandResult_LOAD (LoadSDNode *N, SDOperand &Lo, SDOperand &Hi);
+
+ void ExpandResult_Logical (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandResult_ADDSUB (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandResult_SELECT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandResult_SELECT_CC (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandResult_MUL (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandResult_Shift (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+
+ void ExpandShiftByConstant(SDNode *N, unsigned Amt,
+ SDOperand &Lo, SDOperand &Hi);
+ bool ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+
+ // Operand Promotion.
+ bool PromoteOperand(SDNode *N, unsigned OperandNo);
+ SDOperand PromoteOperand_ANY_EXTEND(SDNode *N);
+ SDOperand PromoteOperand_ZERO_EXTEND(SDNode *N);
+ SDOperand PromoteOperand_SIGN_EXTEND(SDNode *N);
+ SDOperand PromoteOperand_FP_EXTEND(SDNode *N);
+ SDOperand PromoteOperand_FP_ROUND(SDNode *N);
+ SDOperand PromoteOperand_SELECT(SDNode *N, unsigned OpNo);
+ SDOperand PromoteOperand_BRCOND(SDNode *N, unsigned OpNo);
+ SDOperand PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo);
+
+ // Operand Expansion.
+ bool ExpandOperand(SDNode *N, unsigned OperandNo);
+ SDOperand ExpandOperand_TRUNCATE(SDNode *N);
+ SDOperand ExpandOperand_EXTRACT_ELEMENT(SDNode *N);
+ SDOperand ExpandOperand_SETCC(SDNode *N);
+ SDOperand ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo);
+
+ void ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
+ ISD::CondCode &CCCode);
+};
+} // end anonymous namespace
+
+
+
+/// run - This is the main entry point for the type legalizer. This does a
+/// top-down traversal of the dag, legalizing types as it goes.
+void DAGTypeLegalizer::run() {
+ // Create a dummy node (which is not added to allnodes), that adds a reference
+ // to the root node, preventing it from being deleted, and tracking any
+ // changes of the root.
+ HandleSDNode Dummy(DAG.getRoot());
+
+ // The root of the dag may dangle to deleted nodes until the type legalizer is
+ // done. Set it to null to avoid confusion.
+ DAG.setRoot(SDOperand());
+
+ // Walk all nodes in the graph, assigning them a NodeID of 'ReadyToProcess'
+ // (and remembering them) if they are leafs and assigning 'NewNode' if
+ // non-leaves.
+ for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
+ E = DAG.allnodes_end(); I != E; ++I) {
+ if (I->getNumOperands() == 0) {
+ I->setNodeId(ReadyToProcess);
+ Worklist.push_back(I);
+ } else {
+ I->setNodeId(NewNode);
+ }
+ }
+
+ // Now that we have a set of nodes to process, handle them all.
+ while (!Worklist.empty()) {
+ SDNode *N = Worklist.back();
+ Worklist.pop_back();
+ assert(N->getNodeId() == ReadyToProcess &&
+ "Node should be ready if on worklist!");
+
+ // Scan the values produced by the node, checking to see if any result
+ // types are illegal.
+ unsigned i = 0;
+ unsigned NumResults = N->getNumValues();
+ do {
+ LegalizeAction Action = getTypeAction(N->getValueType(i));
+ if (Action == Promote) {
+ PromoteResult(N, i);
+ goto NodeDone;
+ } else if (Action == Expand) {
+ ExpandResult(N, i);
+ goto NodeDone;
+ } else {
+ assert(Action == Legal && "Unknown action!");
+ }
+ } while (++i < NumResults);
+
+ // Scan the operand list for the node, handling any nodes with operands that
+ // are illegal.
+ {
+ unsigned NumOperands = N->getNumOperands();
+ bool NeedsRevisit = false;
+ for (i = 0; i != NumOperands; ++i) {
+ LegalizeAction Action = getTypeAction(N->getOperand(i).getValueType());
+ if (Action == Promote) {
+ NeedsRevisit = PromoteOperand(N, i);
+ break;
+ } else if (Action == Expand) {
+ NeedsRevisit = ExpandOperand(N, i);
+ break;
+ } else {
+ assert(Action == Legal && "Unknown action!");
+ }
+ }
+
+ // If the node needs revisitation, don't add all users to the worklist etc.
+ if (NeedsRevisit)
+ continue;
+
+ if (i == NumOperands)
+ DEBUG(cerr << "Legally typed node: "; N->dump(&DAG); cerr << "\n");
+ }
+NodeDone:
+
+ // If we reach here, the node was processed, potentially creating new nodes.
+ // Mark it as processed and add its users to the worklist as appropriate.
+ N->setNodeId(Processed);
+
+ for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end();
+ UI != E; ++UI) {
+ SDNode *User = *UI;
+ int NodeID = User->getNodeId();
+ assert(NodeID != ReadyToProcess && NodeID != Processed &&
+ "Invalid node id for user of unprocessed node!");
+
+ // This node has two options: it can either be a new node or its Node ID
+ // may be a count of the number of operands it has that are not ready.
+ if (NodeID > 0) {
+ User->setNodeId(NodeID-1);
+
+ // If this was the last use it was waiting on, add it to the ready list.
+ if (NodeID-1 == ReadyToProcess)
+ Worklist.push_back(User);
+ continue;
+ }
+
+ // Otherwise, this node is new: this is the first operand of it that
+ // became ready. Its new NodeID is the number of operands it has minus 1
+ // (as this node is now processed).
+ assert(NodeID == NewNode && "Unknown node ID!");
+ User->setNodeId(User->getNumOperands()-1);
+
+ // If the node only has a single operand, it is now ready.
+ if (User->getNumOperands() == 1)
+ Worklist.push_back(User);
+ }
+ }
+
+ // If the root changed (e.g. it was a dead load, update the root).
+ DAG.setRoot(Dummy.getValue());
+
+ //DAG.viewGraph();
+
+ // Remove dead nodes. This is important to do for cleanliness but also before
+ // the checking loop below. Implicit folding by the DAG.getNode operators can
+ // cause unreachable nodes to be around with their flags set to new.
+ DAG.RemoveDeadNodes();
+
+ // In a debug build, scan all the nodes to make sure we found them all. This
+ // ensures that there are no cycles and that everything got processed.
+#ifndef NDEBUG
+ for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
+ E = DAG.allnodes_end(); I != E; ++I) {
+ if (I->getNodeId() == Processed)
+ continue;
+ cerr << "Unprocessed node: ";
+ I->dump(&DAG); cerr << "\n";
+
+ if (I->getNodeId() == NewNode)
+ cerr << "New node not 'noticed'?\n";
+ else if (I->getNodeId() > 0)
+ cerr << "Operand not processed?\n";
+ else if (I->getNodeId() == ReadyToProcess)
+ cerr << "Not added to worklist?\n";
+ abort();
+ }
+#endif
+}
+
+/// MarkNewNodes - The specified node is the root of a subtree of potentially
+/// new nodes. Add the correct NodeId to mark it.
+void DAGTypeLegalizer::MarkNewNodes(SDNode *N) {
+ // If this was an existing node that is already done, we're done.
+ if (N->getNodeId() != NewNode)
+ return;
+
+ // Okay, we know that this node is new. Recursively walk all of its operands
+ // to see if they are new also. The depth of this walk is bounded by the size
+ // of the new tree that was constructed (usually 2-3 nodes), so we don't worry
+ // about revisitation of nodes.
+ //
+ // As we walk the operands, keep track of the number of nodes that are
+ // processed. If non-zero, this will become the new nodeid of this node.
+ unsigned NumProcessed = 0;
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+ int OpId = N->getOperand(i).Val->getNodeId();
+ if (OpId == NewNode)
+ MarkNewNodes(N->getOperand(i).Val);
+ else if (OpId == Processed)
+ ++NumProcessed;
+ }
+
+ N->setNodeId(N->getNumOperands()-NumProcessed);
+ if (N->getNodeId() == ReadyToProcess)
+ Worklist.push_back(N);
+}
+
+/// ReplaceLegalValueWith - The specified value with a legal type was legalized
+/// to the specified other value. If they are different, update the DAG and
+/// NodeIDs replacing any uses of From to use To instead.
+void DAGTypeLegalizer::ReplaceLegalValueWith(SDOperand From, SDOperand To) {
+ if (From == To) return;
+
+ // If expansion produced new nodes, make sure they are properly marked.
+ if (To.Val->getNodeId() == NewNode)
+ MarkNewNodes(To.Val);
+
+ // Anything that used the old node should now use the new one. Note that this
+ // can potentially cause recursive merging.
+ DAG.ReplaceAllUsesOfValueWith(From, To);
+
+ // Since we just made an unstructured update to the DAG, which could wreak
+ // general havoc on anything that once used N and now uses Res, walk all users
+ // of the result, updating their flags.
+ for (SDNode::use_iterator I = To.Val->use_begin(), E = To.Val->use_end();
+ I != E; ++I) {
+ SDNode *User = *I;
+ // If the node isn't already processed or in the worklist, mark it as new,
+ // then use MarkNewNodes to recompute its ID.
+ int NodeId = User->getNodeId();
+ if (NodeId != ReadyToProcess && NodeId != Processed) {
+ User->setNodeId(NewNode);
+ MarkNewNodes(User);
+ }
+ }
+}
+
+void DAGTypeLegalizer::SetPromotedOp(SDOperand Op, SDOperand Result) {
+ if (Result.Val->getNodeId() == NewNode)
+ MarkNewNodes(Result.Val);
+
+ SDOperand &OpEntry = PromotedNodes[Op];
+ assert(OpEntry.Val == 0 && "Node is already promoted!");
+ OpEntry = Result;
+}
+
+
+void DAGTypeLegalizer::GetExpandedOp(SDOperand Op, SDOperand &Lo,
+ SDOperand &Hi) {
+ std::pair &Entry = ExpandedNodes[Op];
+ assert(Entry.first.Val && "Operand isn't expanded");
+ Lo = Entry.first;
+ Hi = Entry.second;
+}
+
+void DAGTypeLegalizer::SetExpandedOp(SDOperand Op, SDOperand Lo,
+ SDOperand Hi) {
+ // Remember that this is the result of the node.
+ std::pair &Entry = ExpandedNodes[Op];
+ assert(Entry.first.Val == 0 && "Node already expanded");
+ Entry.first = Lo;
+ Entry.second = Hi;
+
+ // Lo/Hi may have been newly allocated, if so, add nodeid's as relevant.
+ if (Lo.Val->getNodeId() == NewNode)
+ MarkNewNodes(Lo.Val);
+ if (Hi.Val->getNodeId() == NewNode)
+ MarkNewNodes(Hi.Val);
+}
+
+//===----------------------------------------------------------------------===//
+// Result Promotion
+//===----------------------------------------------------------------------===//
+
+/// PromoteResult - This method is called when a result of a node is found to be
+/// in need of promotion to a larger type. At this point, the node may also
+/// have invalid operands or may have other results that need expansion, we just
+/// know that (at least) the one result needs promotion.
+void DAGTypeLegalizer::PromoteResult(SDNode *N, unsigned ResNo) {
+ DEBUG(cerr << "Promote node result: "; N->dump(&DAG); cerr << "\n");
+ SDOperand Result = SDOperand();
+
+ switch (N->getOpcode()) {
+ default:
+#ifndef NDEBUG
+ cerr << "PromoteResult #" << ResNo << ": ";
+ N->dump(&DAG); cerr << "\n";
+#endif
+ assert(0 && "Do not know how to promote this operator!");
+ abort();
+ case ISD::UNDEF: Result = PromoteResult_UNDEF(N); break;
+ case ISD::Constant: Result = PromoteResult_Constant(N); break;
+
+ case ISD::TRUNCATE: Result = PromoteResult_TRUNCATE(N); break;
+ case ISD::SIGN_EXTEND:
+ case ISD::ZERO_EXTEND:
+ case ISD::ANY_EXTEND: Result = PromoteResult_INT_EXTEND(N); break;
+ case ISD::FP_ROUND: Result = PromoteResult_FP_ROUND(N); break;
+
+ case ISD::SETCC: Result = PromoteResult_SETCC(N); break;
+ case ISD::LOAD: Result = PromoteResult_LOAD(cast(N)); break;
+
+ case ISD::AND:
+ case ISD::OR:
+ case ISD::XOR:
+ case ISD::ADD:
+ case ISD::SUB:
+ case ISD::MUL: Result = PromoteResult_SimpleIntBinOp(N); break;
+ }
+
+ // If Result is null, the sub-method took care of registering the result.
+ if (Result.Val)
+ SetPromotedOp(SDOperand(N, ResNo), Result);
+}
+
+SDOperand DAGTypeLegalizer::PromoteResult_UNDEF(SDNode *N) {
+ return DAG.getNode(ISD::UNDEF, TLI.getTypeToTransformTo(N->getValueType(0)));
+}
+
+SDOperand DAGTypeLegalizer::PromoteResult_Constant(SDNode *N) {
+ MVT::ValueType VT = N->getValueType(0);
+ // Zero extend things like i1, sign extend everything else. It shouldn't
+ // matter in theory which one we pick, but this tends to give better code?
+ unsigned Opc = VT != MVT::i1 ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
+ SDOperand Result = DAG.getNode(Opc, TLI.getTypeToTransformTo(VT),
+ SDOperand(N, 0));
+ assert(isa(Result) && "Didn't constant fold ext?");
+ return Result;
+}
+
+SDOperand DAGTypeLegalizer::PromoteResult_TRUNCATE(SDNode *N) {
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ switch (getTypeAction(N->getOperand(0).getValueType())) {
+ default: assert(0 && "Unknown type action!");
+ case Legal: {
+ SDOperand Res = N->getOperand(0);
+ assert(Res.getValueType() >= NVT && "Truncation doesn't make sense!");
+ if (Res.getValueType() > NVT) // Truncate to NVT instead of VT
+ return DAG.getNode(ISD::TRUNCATE, NVT, Res);
+ return Res;
+ }
+ case Promote:
+ // The truncation is not required, because we don't guarantee anything
+ // about high bits anyway.
+ return GetPromotedOp(N->getOperand(0));
+ case Expand:
+ // Truncate the low part of the expanded value to the result type
+ SDOperand Lo, Hi;
+ GetExpandedOp(N->getOperand(0), Lo, Hi);
+ return DAG.getNode(ISD::TRUNCATE, NVT, Lo);
+ }
+}
+SDOperand DAGTypeLegalizer::PromoteResult_INT_EXTEND(SDNode *N) {
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ switch (getTypeAction(N->getOperand(0).getValueType())) {
+ default: assert(0 && "BUG: Smaller reg should have been promoted!");
+ case Legal:
+ // Input is legal? Just do extend all the way to the larger type.
+ return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0));
+ case Promote:
+ // Get promoted operand if it is smaller.
+ SDOperand Res = GetPromotedOp(N->getOperand(0));
+ // The high bits are not guaranteed to be anything. Insert an extend.
+ if (N->getOpcode() == ISD::SIGN_EXTEND)
+ return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res,
+ DAG.getValueType(N->getOperand(0).getValueType()));
+ if (N->getOpcode() == ISD::ZERO_EXTEND)
+ return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType());
+ assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
+ return Res;
+ }
+}
+
+SDOperand DAGTypeLegalizer::PromoteResult_FP_ROUND(SDNode *N) {
+ // NOTE: Assumes input is legal.
+ return DAG.getNode(ISD::FP_ROUND_INREG, N->getOperand(0).getValueType(),
+ N->getOperand(0), DAG.getValueType(N->getValueType(0)));
+}
+
+
+SDOperand DAGTypeLegalizer::PromoteResult_SETCC(SDNode *N) {
+ assert(isTypeLegal(TLI.getSetCCResultTy()) && "SetCC type is not legal??");
+ return DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), N->getOperand(0),
+ N->getOperand(1), N->getOperand(2));
+}
+
+SDOperand DAGTypeLegalizer::PromoteResult_LOAD(LoadSDNode *N) {
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ ISD::LoadExtType ExtType =
+ ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType();
+ SDOperand Res = DAG.getExtLoad(ExtType, NVT, N->getChain(), N->getBasePtr(),
+ N->getSrcValue(), N->getSrcValueOffset(),
+ N->getLoadedVT(), N->isVolatile(),
+ N->getAlignment());
+
+ // Legalized the chain result, switching anything that used the old chain to
+ // use the new one.
+ ReplaceLegalValueWith(SDOperand(N, 1), Res.getValue(1));
+ return Res;
+}
+
+SDOperand DAGTypeLegalizer::PromoteResult_SimpleIntBinOp(SDNode *N) {
+ // The input may have strange things in the top bits of the registers, but
+ // these operations don't care. They may have weird bits going out, but
+ // that too is okay if they are integer operations.
+ SDOperand LHS = GetPromotedOp(N->getOperand(0));
+ SDOperand RHS = GetPromotedOp(N->getOperand(1));
+ return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
+}
+
+//===----------------------------------------------------------------------===//
+// Result Expansion
+//===----------------------------------------------------------------------===//
+
+/// ExpandResult - This method is called when the specified result of the
+/// specified node is found to need expansion. At this point, the node may also
+/// have invalid operands or may have other results that need promotion, we just
+/// know that (at least) the one result needs expansion.
+void DAGTypeLegalizer::ExpandResult(SDNode *N, unsigned ResNo) {
+ DEBUG(cerr << "Expand node result: "; N->dump(&DAG); cerr << "\n");
+ SDOperand Lo, Hi;
+ Lo = Hi = SDOperand();
+ switch (N->getOpcode()) {
+ default:
+#ifndef NDEBUG
+ cerr << "ExpandResult #" << ResNo << ": ";
+ N->dump(&DAG); cerr << "\n";
+#endif
+ assert(0 && "Do not know how to expand this operator!");
+ abort();
+
+ case ISD::UNDEF: ExpandResult_UNDEF(N, Lo, Hi); break;
+ case ISD::Constant: ExpandResult_Constant(N, Lo, Hi); break;
+ case ISD::BUILD_PAIR: ExpandResult_BUILD_PAIR(N, Lo, Hi); break;
+ case ISD::ANY_EXTEND: ExpandResult_ANY_EXTEND(N, Lo, Hi); break;
+ case ISD::ZERO_EXTEND: ExpandResult_ZERO_EXTEND(N, Lo, Hi); break;
+ case ISD::SIGN_EXTEND: ExpandResult_SIGN_EXTEND(N, Lo, Hi); break;
+ case ISD::LOAD: ExpandResult_LOAD(cast(N), Lo, Hi); break;
+
+ case ISD::AND:
+ case ISD::OR:
+ case ISD::XOR: ExpandResult_Logical(N, Lo, Hi); break;
+ case ISD::ADD:
+ case ISD::SUB: ExpandResult_ADDSUB(N, Lo, Hi); break;
+ case ISD::SELECT: ExpandResult_SELECT(N, Lo, Hi); break;
+ case ISD::SELECT_CC: ExpandResult_SELECT_CC(N, Lo, Hi); break;
+ case ISD::MUL: ExpandResult_MUL(N, Lo, Hi); break;
+ case ISD::SHL:
+ case ISD::SRA:
+ case ISD::SRL: ExpandResult_Shift(N, Lo, Hi); break;
+
+ }
+
+ // If Lo/Hi is null, the sub-method took care of registering results etc.
+ if (Lo.Val)
+ SetExpandedOp(SDOperand(N, ResNo), Lo, Hi);
+}
+
+void DAGTypeLegalizer::ExpandResult_UNDEF(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ MVT::ValueType NVT = TLI.getTypeToExpandTo(N->getValueType(0));
+ Lo = Hi = DAG.getNode(ISD::UNDEF, NVT);
+}
+
+void DAGTypeLegalizer::ExpandResult_Constant(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ MVT::ValueType NVT = TLI.getTypeToExpandTo(N->getValueType(0));
+ uint64_t Cst = cast(N)->getValue();
+ Lo = DAG.getConstant(Cst, NVT);
+ Hi = DAG.getConstant(Cst >> MVT::getSizeInBits(NVT), NVT);
+}
+
+void DAGTypeLegalizer::ExpandResult_BUILD_PAIR(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ // Return the operands.
+ Lo = N->getOperand(0);
+ Hi = N->getOperand(1);
+}
+
+void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+
+ MVT::ValueType NVT = TLI.getTypeToExpandTo(N->getValueType(0));
+ // The low part is any extension of the input (which degenerates to a copy).
+ Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, N->getOperand(0));
+ Hi = DAG.getNode(ISD::UNDEF, NVT); // The high part is undefined.
+}
+
+void DAGTypeLegalizer::ExpandResult_ZERO_EXTEND(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ MVT::ValueType NVT = TLI.getTypeToExpandTo(N->getValueType(0));
+ // The low part is zero extension of the input (which degenerates to a copy).
+ Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0));
+ Hi = DAG.getConstant(0, NVT); // The high part is just a zero.
+}
+
+void DAGTypeLegalizer::ExpandResult_SIGN_EXTEND(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ MVT::ValueType NVT = TLI.getTypeToExpandTo(N->getValueType(0));
+ // The low part is sign extension of the input (which degenerates to a copy).
+ Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0));
+
+ // The high part is obtained by SRA'ing all but one of the bits of low part.
+ unsigned LoSize = MVT::getSizeInBits(NVT);
+ Hi = DAG.getNode(ISD::SRA, NVT, Lo,
+ DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
+}
+
+
+void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ MVT::ValueType VT = N->getValueType(0);
+ MVT::ValueType NVT = TLI.getTypeToExpandTo(VT);
+ SDOperand Ch = N->getChain(); // Legalize the chain.
+ SDOperand Ptr = N->getBasePtr(); // Legalize the pointer.
+ ISD::LoadExtType ExtType = N->getExtensionType();
+ int SVOffset = N->getSrcValueOffset();
+ unsigned Alignment = N->getAlignment();
+ bool isVolatile = N->isVolatile();
+
+ if (ExtType == ISD::NON_EXTLOAD) {
+ Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
+ isVolatile, Alignment);
+ if (VT == MVT::f32 || VT == MVT::f64) {
+ assert(0 && "FIXME: softfp should use promotion!");
+#if 0
+ // f32->i32 or f64->i64 one to one expansion.
+ // Remember that we legalized the chain.
+ AddLegalizedOperand(SDOperand(Node, 1), LegalizeOp(Lo.getValue(1)));
+ // Recursively expand the new load.
+ if (getTypeAction(NVT) == Expand)
+ ExpandOp(Lo, Lo, Hi);
+ break;
+#endif
+ }
+
+ // Increment the pointer to the other half.
+ unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8;
+ Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ getIntPtrConstant(IncrementSize));
+ Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
+ isVolatile, std::max(Alignment, IncrementSize));
+
+ // Build a factor node to remember that this load is independent of the
+ // other one.
+ Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+ Hi.getValue(1));
+
+ // Handle endianness of the load.
+ if (!TLI.isLittleEndian())
+ std::swap(Lo, Hi);
+ } else {
+ MVT::ValueType EVT = N->getLoadedVT();
+
+ if (VT == MVT::f64 && EVT == MVT::f32) {
+ assert(0 && "FIXME: softfp should use promotion!");
+#if 0
+ // f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND
+ SDOperand Load = DAG.getLoad(EVT, Ch, Ptr, N->getSrcValue(),
+ SVOffset, isVolatile, Alignment);
+ // Remember that we legalized the chain.
+ AddLegalizedOperand(SDOperand(Node, 1), LegalizeOp(Load.getValue(1)));
+ ExpandOp(DAG.getNode(ISD::FP_EXTEND, VT, Load), Lo, Hi);
+ break;
+#endif
+ }
+
+ if (EVT == NVT)
+ Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(),
+ SVOffset, isVolatile, Alignment);
+ else
+ Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(),
+ SVOffset, EVT, isVolatile,
+ Alignment);
+ // Remember the chain.
+ Ch = Lo.getValue(1);
+
+ if (ExtType == ISD::SEXTLOAD) {
+ // The high part is obtained by SRA'ing all but one of the bits of the
+ // lo part.
+ unsigned LoSize = MVT::getSizeInBits(Lo.getValueType());
+ Hi = DAG.getNode(ISD::SRA, NVT, Lo,
+ DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
+ } else if (ExtType == ISD::ZEXTLOAD) {
+ // The high part is just a zero.
+ Hi = DAG.getConstant(0, NVT);
+ } else {
+ assert(ExtType == ISD::EXTLOAD && "Unknown extload!");
+ // The high part is undefined.
+ Hi = DAG.getNode(ISD::UNDEF, NVT);
+ }
+ }
+
+ // Legalized the chain result, switching anything that used the old chain to
+ // use the new one.
+ ReplaceLegalValueWith(SDOperand(N, 1), Ch);
+}
+
+
+void DAGTypeLegalizer::ExpandResult_Logical(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ SDOperand LL, LH, RL, RH;
+ GetExpandedOp(N->getOperand(0), LL, LH);
+ GetExpandedOp(N->getOperand(1), RL, RH);
+ Lo = DAG.getNode(N->getOpcode(), LL.getValueType(), LL, RL);
+ Hi = DAG.getNode(N->getOpcode(), LL.getValueType(), LH, RH);
+}
+
+void DAGTypeLegalizer::ExpandResult_SELECT(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ SDOperand LL, LH, RL, RH;
+ GetExpandedOp(N->getOperand(1), LL, LH);
+ GetExpandedOp(N->getOperand(2), RL, RH);
+ Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LL, RL);
+
+ assert(N->getOperand(0).getValueType() != MVT::f32 &&
+ "FIXME: softfp shouldn't use expand!");
+ Hi = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LH, RH);
+}
+
+void DAGTypeLegalizer::ExpandResult_SELECT_CC(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ SDOperand LL, LH, RL, RH;
+ GetExpandedOp(N->getOperand(2), LL, LH);
+ GetExpandedOp(N->getOperand(3), RL, RH);
+ Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0),
+ N->getOperand(1), LL, RL, N->getOperand(4));
+
+ assert(N->getOperand(0).getValueType() != MVT::f32 &&
+ "FIXME: softfp shouldn't use expand!");
+ Hi = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0),
+ N->getOperand(1), LH, RH, N->getOperand(4));
+}
+
+void DAGTypeLegalizer::ExpandResult_ADDSUB(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ MVT::ValueType VT = N->getValueType(0);
+
+ // If the target wants to custom expand this, let them.
+ if (TLI.getOperationAction(N->getOpcode(), VT) ==
+ TargetLowering::Custom) {
+ SDOperand Op = TLI.LowerOperation(SDOperand(N, 0), DAG);
+ // FIXME: Do a replace all uses with here!
+ assert(0 && "Custom not impl yet!");
+ if (Op.Val) {
+#if 0
+ ExpandOp(Op, Lo, Hi);
+#endif
+ return;
+ }
+ }
+
+ // Expand the subcomponents.
+ SDOperand LHSL, LHSH, RHSL, RHSH;
+ GetExpandedOp(N->getOperand(0), LHSL, LHSH);
+ GetExpandedOp(N->getOperand(1), RHSL, RHSH);
+ SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
+ SDOperand LoOps[2], HiOps[3];
+ LoOps[0] = LHSL;
+ LoOps[1] = RHSL;
+ HiOps[0] = LHSH;
+ HiOps[1] = RHSH;
+ if (N->getOpcode() == ISD::ADD) {
+ Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
+ HiOps[2] = Lo.getValue(1);
+ Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
+ } else {
+ Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2);
+ HiOps[2] = Lo.getValue(1);
+ Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3);
+ }
+}
+
+
+void DAGTypeLegalizer::ExpandResult_MUL(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ MVT::ValueType VT = N->getValueType(0);
+ MVT::ValueType NVT = TLI.getTypeToExpandTo(VT);
+
+ // If the target wants to custom expand this, let them.
+ if (TLI.getOperationAction(ISD::MUL, VT) == TargetLowering::Custom) {
+ SDOperand New = TLI.LowerOperation(SDOperand(N, 0), DAG);
+ if (New.Val) {
+ // FIXME: Do a replace all uses with here!
+ assert(0 && "Custom not impl yet!");
+#if 0
+ ExpandOp(New, Lo, Hi);
+#endif
+ return;
+ }
+ }
+
+ bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT);
+ bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT);
+ bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT);
+ bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT);
+ if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) {
+ SDOperand LL, LH, RL, RH;
+ GetExpandedOp(N->getOperand(0), LL, LH);
+ GetExpandedOp(N->getOperand(1), RL, RH);
+ unsigned BitSize = MVT::getSizeInBits(RH.getValueType());
+ unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
+ unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
+
+ // FIXME: generalize this to handle other bit sizes
+ if (LHSSB == 32 && RHSSB == 32 &&
+ DAG.MaskedValueIsZero(N->getOperand(0), 0xFFFFFFFF00000000ULL) &&
+ DAG.MaskedValueIsZero(N->getOperand(1), 0xFFFFFFFF00000000ULL)) {
+ // The inputs are both zero-extended.
+ if (HasUMUL_LOHI) {
+ // We can emit a umul_lohi.
+ Lo = DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL);
+ Hi = SDOperand(Lo.Val, 1);
+ return;
+ }
+ if (HasMULHU) {
+ // We can emit a mulhu+mul.
+ Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
+ Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
+ return;
+ }
+ }
+ if (LHSSB > BitSize && RHSSB > BitSize) {
+ // The input values are both sign-extended.
+ if (HasSMUL_LOHI) {
+ // We can emit a smul_lohi.
+ Lo = DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL);
+ Hi = SDOperand(Lo.Val, 1);
+ return;
+ }
+ if (HasMULHS) {
+ // We can emit a mulhs+mul.
+ Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
+ Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL);
+ return;
+ }
+ }
+ if (HasUMUL_LOHI) {
+ // Lo,Hi = umul LHS, RHS.
+ SDOperand UMulLOHI = DAG.getNode(ISD::UMUL_LOHI,
+ DAG.getVTList(NVT, NVT), LL, RL);
+ Lo = UMulLOHI;
+ Hi = UMulLOHI.getValue(1);
+ RH = DAG.getNode(ISD::MUL, NVT, LL, RH);
+ LH = DAG.getNode(ISD::MUL, NVT, LH, RL);
+ Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH);
+ Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
+ return;
+ }
+ }
+
+ abort();
+#if 0 // FIXME!
+ // If nothing else, we can make a libcall.
+ Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::MUL_I64), N,
+ false/*sign irrelevant*/, Hi);
+#endif
+}
+
+
+void DAGTypeLegalizer::ExpandResult_Shift(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ MVT::ValueType VT = N->getValueType(0);
+
+ // If the target wants custom lowering, do so.
+ if (TLI.getOperationAction(N->getOpcode(), VT) == TargetLowering::Custom) {
+ SDOperand Op = TLI.LowerOperation(SDOperand(N, 0), DAG);
+ if (Op.Val) {
+ // Now that the custom expander is done, expand the result, which is
+ // still VT.
+ // FIXME: Do a replace all uses with here!
+ abort();
+#if 0
+ ExpandOp(Op, Lo, Hi);
+#endif
+ return;
+ }
+ }
+
+ // If we can emit an efficient shift operation, do so now. Check to see if
+ // the RHS is a constant.
+ if (ConstantSDNode *CN = dyn_cast(N->getOperand(1)))
+ return ExpandShiftByConstant(N, CN->getValue(), Lo, Hi);
+
+ // If we can determine that the high bit of the shift is zero or one, even if
+ // the low bits are variable, emit this shift in an optimized form.
+ if (ExpandShiftWithKnownAmountBit(N, Lo, Hi))
+ return;
+
+ // If this target supports shift_PARTS, use it. First, map to the _PARTS opc.
+ unsigned PartsOpc;
+ if (N->getOpcode() == ISD::SHL)
+ PartsOpc = ISD::SHL_PARTS;
+ else if (N->getOpcode() == ISD::SRL)
+ PartsOpc = ISD::SRL_PARTS;
+ else {
+ assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
+ PartsOpc = ISD::SRA_PARTS;
+ }
+
+ // Next check to see if the target supports this SHL_PARTS operation or if it
+ // will custom expand it.
+ MVT::ValueType NVT = TLI.getTypeToExpandTo(VT);
+ TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT);
+ if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
+ Action == TargetLowering::Custom) {
+ // Expand the subcomponents.
+ SDOperand LHSL, LHSH;
+ GetExpandedOp(N->getOperand(0), LHSL, LHSH);
+
+ SDOperand Ops[] = { LHSL, LHSH, N->getOperand(1) };
+ MVT::ValueType VT = LHSL.getValueType();
+ Lo = DAG.getNode(PartsOpc, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3);
+ Hi = Lo.getValue(1);
+ return;
+ }
+
+ abort();
+#if 0 // FIXME!
+ // Otherwise, emit a libcall.
+ unsigned RuntimeCode = ; // SRL -> SRL_I64 etc.
+ bool Signed = ;
+ Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::SRL_I64), N,
+ false/*lshr is unsigned*/, Hi);
+#endif
+}
+
+
+/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded,
+/// and the shift amount is a constant 'Amt'. Expand the operation.
+void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
+ SDOperand &Lo, SDOperand &Hi) {
+ // Expand the incoming operand to be shifted, so that we have its parts
+ SDOperand InL, InH;
+ GetExpandedOp(N->getOperand(0), InL, InH);
+
+ MVT::ValueType NVT = InL.getValueType();
+ unsigned VTBits = MVT::getSizeInBits(N->getValueType(0));
+ unsigned NVTBits = MVT::getSizeInBits(NVT);
+ MVT::ValueType ShTy = N->getOperand(1).getValueType();
+
+ if (N->getOpcode() == ISD::SHL) {
+ if (Amt > VTBits) {
+ Lo = Hi = DAG.getConstant(0, NVT);
+ } else if (Amt > NVTBits) {
+ Lo = DAG.getConstant(0, NVT);
+ Hi = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt-NVTBits,ShTy));
+ } else if (Amt == NVTBits) {
+ Lo = DAG.getConstant(0, NVT);
+ Hi = InL;
+ } else {
+ Lo = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt, ShTy));
+ Hi = DAG.getNode(ISD::OR, NVT,
+ DAG.getNode(ISD::SHL, NVT, InH,
+ DAG.getConstant(Amt, ShTy)),
+ DAG.getNode(ISD::SRL, NVT, InL,
+ DAG.getConstant(NVTBits-Amt, ShTy)));
+ }
+ return;
+ }
+
+ if (N->getOpcode() == ISD::SRL) {
+ if (Amt > VTBits) {
+ Lo = DAG.getConstant(0, NVT);
+ Hi = DAG.getConstant(0, NVT);
+ } else if (Amt > NVTBits) {
+ Lo = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy));
+ Hi = DAG.getConstant(0, NVT);
+ } else if (Amt == NVTBits) {
+ Lo = InH;
+ Hi = DAG.getConstant(0, NVT);
+ } else {
+ Lo = DAG.getNode(ISD::OR, NVT,
+ DAG.getNode(ISD::SRL, NVT, InL,
+ DAG.getConstant(Amt, ShTy)),
+ DAG.getNode(ISD::SHL, NVT, InH,
+ DAG.getConstant(NVTBits-Amt, ShTy)));
+ Hi = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt, ShTy));
+ }
+ return;
+ }
+
+ assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
+ if (Amt > VTBits) {
+ Hi = Lo = DAG.getNode(ISD::SRA, NVT, InH,
+ DAG.getConstant(NVTBits-1, ShTy));
+ } else if (Amt > NVTBits) {
+ Lo = DAG.getNode(ISD::SRA, NVT, InH,
+ DAG.getConstant(Amt-NVTBits, ShTy));
+ Hi = DAG.getNode(ISD::SRA, NVT, InH,
+ DAG.getConstant(NVTBits-1, ShTy));
+ } else if (Amt == NVTBits) {
+ Lo = InH;
+ Hi = DAG.getNode(ISD::SRA, NVT, InH,
+ DAG.getConstant(NVTBits-1, ShTy));
+ } else {
+ Lo = DAG.getNode(ISD::OR, NVT,
+ DAG.getNode(ISD::SRL, NVT, InL,
+ DAG.getConstant(Amt, ShTy)),
+ DAG.getNode(ISD::SHL, NVT, InH,
+ DAG.getConstant(NVTBits-Amt, ShTy)));
+ Hi = DAG.getNode(ISD::SRA, NVT, InH, DAG.getConstant(Amt, ShTy));
+ }
+}
+
+/// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify
+/// this shift based on knowledge of the high bit of the shift amount. If we
+/// can tell this, we know that it is >= 32 or < 32, without knowing the actual
+/// shift amount.
+bool DAGTypeLegalizer::
+ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ unsigned NVTBits = MVT::getSizeInBits(NVT);
+
+ uint64_t HighBitMask = NVTBits, KnownZero, KnownOne;
+ DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne);
+
+ // If we don't know anything about the high bit, exit.
+ if (((KnownZero|KnownOne) & HighBitMask) == 0)
+ return false;
+
+ // Get the incoming operand to be shifted.
+ SDOperand InL, InH;
+ GetExpandedOp(N->getOperand(0), InL, InH);
+ SDOperand Amt = N->getOperand(1);
+
+ // If we know that the high bit of the shift amount is one, then we can do
+ // this as a couple of simple shifts.
+ if (KnownOne & HighBitMask) {
+ // Mask out the high bit, which we know is set.
+ Amt = DAG.getNode(ISD::AND, Amt.getValueType(), Amt,
+ DAG.getConstant(NVTBits-1, Amt.getValueType()));
+
+ switch (N->getOpcode()) {
+ default: assert(0 && "Unknown shift");
+ case ISD::SHL:
+ Lo = DAG.getConstant(0, NVT); // Low part is zero.
+ Hi = DAG.getNode(ISD::SHL, NVT, InL, Amt); // High part from Lo part.
+ return true;
+ case ISD::SRL:
+ Hi = DAG.getConstant(0, NVT); // Hi part is zero.
+ Lo = DAG.getNode(ISD::SRL, NVT, InH, Amt); // Lo part from Hi part.
+ return true;
+ case ISD::SRA:
+ Hi = DAG.getNode(ISD::SRA, NVT, InH, // Sign extend high part.
+ DAG.getConstant(NVTBits-1, Amt.getValueType()));
+ Lo = DAG.getNode(ISD::SRA, NVT, InH, Amt); // Lo part from Hi part.
+ return true;
+ }
+ }
+
+ // If we know that the high bit of the shift amount is zero, then we can do
+ // this as a couple of simple shifts.
+ assert((KnownZero & HighBitMask) && "Bad mask computation above");
+
+ // Compute 32-amt.
+ SDOperand Amt2 = DAG.getNode(ISD::SUB, Amt.getValueType(),
+ DAG.getConstant(NVTBits, Amt.getValueType()),
+ Amt);
+ unsigned Op1, Op2;
+ switch (N->getOpcode()) {
+ default: assert(0 && "Unknown shift");
+ case ISD::SHL: Op1 = ISD::SHL; Op2 = ISD::SRL; break;
+ case ISD::SRL:
+ case ISD::SRA: Op1 = ISD::SRL; Op2 = ISD::SHL; break;
+ }
+
+ Lo = DAG.getNode(N->getOpcode(), NVT, InL, Amt);
+ Hi = DAG.getNode(ISD::OR, NVT,
+ DAG.getNode(Op1, NVT, InH, Amt),
+ DAG.getNode(Op2, NVT, InL, Amt2));
+ return true;
+}
+
+//===----------------------------------------------------------------------===//
+// Operand Promotion
+//===----------------------------------------------------------------------===//
+
+/// PromoteOperand - This method is called when the specified operand of the
+/// specified node is found to need promotion. At this point, all of the result
+/// types of the node are known to be legal, but other operands of the node may
+/// need promotion or expansion as well as the specified one.
+bool DAGTypeLegalizer::PromoteOperand(SDNode *N, unsigned OpNo) {
+ DEBUG(cerr << "Promote node operand: "; N->dump(&DAG); cerr << "\n");
+ SDOperand Res;
+ switch (N->getOpcode()) {
+ default:
+#ifndef NDEBUG
+ cerr << "PromoteOperand Op #" << OpNo << ": ";
+ N->dump(&DAG); cerr << "\n";
+#endif
+ assert(0 && "Do not know how to promote this operator's operand!");
+ abort();
+
+ case ISD::ANY_EXTEND: Res = PromoteOperand_ANY_EXTEND(N); break;
+ case ISD::ZERO_EXTEND: Res = PromoteOperand_ZERO_EXTEND(N); break;
+ case ISD::SIGN_EXTEND: Res = PromoteOperand_SIGN_EXTEND(N); break;
+ case ISD::FP_EXTEND: Res = PromoteOperand_FP_EXTEND(N); break;
+ case ISD::FP_ROUND: Res = PromoteOperand_FP_ROUND(N); break;
+
+ case ISD::SELECT: Res = PromoteOperand_SELECT(N, OpNo); break;
+ case ISD::BRCOND: Res = PromoteOperand_BRCOND(N, OpNo); break;
+ case ISD::STORE: Res = PromoteOperand_STORE(cast(N),
+ OpNo); break;
+ }
+
+ // If the result is null, the sub-method took care of registering results etc.
+ if (!Res.Val) return false;
+ // If the result is N, the sub-method updated N in place.
+ if (Res.Val == N) {
+ // Mark N as new and remark N and its operands. This allows us to correctly
+ // revisit N if it needs another step of promotion and allows us to visit
+ // any new operands to N.
+ N->setNodeId(NewNode);
+ MarkNewNodes(N);
+ return true;
+ }
+
+ assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
+ "Invalid operand expansion");
+
+ ReplaceLegalValueWith(SDOperand(N, 0), Res);
+ return false;
+}
+
+SDOperand DAGTypeLegalizer::PromoteOperand_ANY_EXTEND(SDNode *N) {
+ SDOperand Op = GetPromotedOp(N->getOperand(0));
+ return DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
+}
+
+SDOperand DAGTypeLegalizer::PromoteOperand_ZERO_EXTEND(SDNode *N) {
+ SDOperand Op = GetPromotedOp(N->getOperand(0));
+ Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
+ return DAG.getZeroExtendInReg(Op, N->getOperand(0).getValueType());
+}
+SDOperand DAGTypeLegalizer::PromoteOperand_SIGN_EXTEND(SDNode *N) {
+ SDOperand Op = GetPromotedOp(N->getOperand(0));
+ Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
+ return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(),
+ Op, DAG.getValueType(N->getOperand(0).getValueType()));
+}
+
+SDOperand DAGTypeLegalizer::PromoteOperand_FP_EXTEND(SDNode *N) {
+ SDOperand Op = GetPromotedOp(N->getOperand(0));
+ return DAG.getNode(ISD::FP_EXTEND, N->getValueType(0), Op);
+}
+SDOperand DAGTypeLegalizer::PromoteOperand_FP_ROUND(SDNode *N) {
+ SDOperand Op = GetPromotedOp(N->getOperand(0));
+ return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Op);
+}
+
+
+SDOperand DAGTypeLegalizer::PromoteOperand_SELECT(SDNode *N, unsigned OpNo) {
+ assert(OpNo == 0 && "Only know how to promote condition");
+ SDOperand Cond = GetPromotedOp(N->getOperand(0)); // Promote the condition.
+
+ // The top bits of the promoted condition are not necessarily zero, ensure
+ // that the value is properly zero extended.
+ if (!DAG.MaskedValueIsZero(Cond,
+ MVT::getIntVTBitMask(Cond.getValueType())^1)) {
+ Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
+ MarkNewNodes(Cond.Val);
+ }
+
+ // The chain (Op#0) and basic block destination (Op#2) are always legal types.
+ return DAG.UpdateNodeOperands(SDOperand(N, 0), Cond, N->getOperand(1),
+ N->getOperand(2));
+}
+
+
+SDOperand DAGTypeLegalizer::PromoteOperand_BRCOND(SDNode *N, unsigned OpNo) {
+ assert(OpNo == 1 && "only know how to promote condition");
+ SDOperand Cond = GetPromotedOp(N->getOperand(1)); // Promote the condition.
+
+ // The top bits of the promoted condition are not necessarily zero, ensure
+ // that the value is properly zero extended.
+ if (!DAG.MaskedValueIsZero(Cond,
+ MVT::getIntVTBitMask(Cond.getValueType())^1)) {
+ Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
+ MarkNewNodes(Cond.Val);
+ }
+
+ // The chain (Op#0) and basic block destination (Op#2) are always legal types.
+ return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), Cond,
+ N->getOperand(2));
+}
+
+SDOperand DAGTypeLegalizer::PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo){
+ SDOperand Ch = N->getChain(), Ptr = N->getBasePtr();
+ int SVOffset = N->getSrcValueOffset();
+ unsigned Alignment = N->getAlignment();
+ bool isVolatile = N->isVolatile();
+
+ SDOperand Val = GetPromotedOp(N->getValue()); // Get promoted value.
+
+ assert(!N->isTruncatingStore() && "Cannot promote this store operand!");
+
+ // Truncate the value and store the result.
+ return DAG.getTruncStore(Ch, Val, Ptr, N->getSrcValue(),
+ SVOffset, N->getStoredVT(),
+ isVolatile, Alignment);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Operand Expansion
+//===----------------------------------------------------------------------===//
+
+/// ExpandOperand - This method is called when the specified operand of the
+/// specified node is found to need expansion. At this point, all of the result
+/// types of the node are known to be legal, but other operands of the node may
+/// need promotion or expansion as well as the specified one.
+bool DAGTypeLegalizer::ExpandOperand(SDNode *N, unsigned OpNo) {
+ DEBUG(cerr << "Expand node operand: "; N->dump(&DAG); cerr << "\n");
+ SDOperand Res;
+ switch (N->getOpcode()) {
+ default:
+#ifndef NDEBUG
+ cerr << "ExpandOperand Op #" << OpNo << ": ";
+ N->dump(&DAG); cerr << "\n";
+#endif
+ assert(0 && "Do not know how to expand this operator's operand!");
+ abort();
+
+ case ISD::TRUNCATE: Res = ExpandOperand_TRUNCATE(N); break;
+ case ISD::EXTRACT_ELEMENT: Res = ExpandOperand_EXTRACT_ELEMENT(N); break;
+ case ISD::SETCC: Res = ExpandOperand_SETCC(N); break;
+
+ case ISD::STORE: Res = ExpandOperand_STORE(cast(N), OpNo); break;
+ }
+
+ // If the result is null, the sub-method took care of registering results etc.
+ if (!Res.Val) return false;
+ // If the result is N, the sub-method updated N in place. Check to see if any
+ // operands are new, and if so, mark them.
+ if (Res.Val == N) {
+ // Mark N as new and remark N and its operands. This allows us to correctly
+ // revisit N if it needs another step of promotion and allows us to visit
+ // any new operands to N.
+ N->setNodeId(NewNode);
+ MarkNewNodes(N);
+ return true;
+ }
+
+ assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
+ "Invalid operand expansion");
+
+ ReplaceLegalValueWith(SDOperand(N, 0), Res);
+ return false;
+}
+
+SDOperand DAGTypeLegalizer::ExpandOperand_TRUNCATE(SDNode *N) {
+ SDOperand InL, InH;
+ GetExpandedOp(N->getOperand(0), InL, InH);
+ // Just truncate the low part of the source.
+ return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), InL);
+}
+
+SDOperand DAGTypeLegalizer::ExpandOperand_EXTRACT_ELEMENT(SDNode *N) {
+ SDOperand Lo, Hi;
+ GetExpandedOp(N->getOperand(0), Lo, Hi);
+ return cast(N->getOperand(1))->getValue() ? Hi : Lo;
+}
+
+SDOperand DAGTypeLegalizer::ExpandOperand_SETCC(SDNode *N) {
+ SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
+ ISD::CondCode CCCode = cast(N->getOperand(2))->get();
+ ExpandSetCCOperands(NewLHS, NewRHS, CCCode);
+
+ // If ExpandSetCCOperands returned a scalar, use it.
+ if (NewRHS.Val == 0) return NewLHS;
+
+ // Otherwise, update N to have the operands specified.
+ return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS,
+ DAG.getCondCode(CCCode));
+}
+
+/// ExpandSetCCOperands - Expand the operands to a comparison. This code is
+/// shared among BR_CC, SELECT_CC, and SETCC handlers.
+void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
+ ISD::CondCode &CCCode) {
+ SDOperand LHSLo, LHSHi, RHSLo, RHSHi;
+ GetExpandedOp(NewLHS, LHSLo, LHSHi);
+ GetExpandedOp(NewRHS, RHSLo, RHSHi);
+
+ MVT::ValueType VT = NewLHS.getValueType();
+ if (VT == MVT::f32 || VT == MVT::f64) {
+ assert(0 && "FIXME: softfp not implemented yet! should be promote not exp");
+ }
+
+ if (VT == MVT::ppcf128) {
+ // FIXME: This generated code sucks. We want to generate
+ // FCMP crN, hi1, hi2
+ // BNE crN, L:
+ // FCMP crN, lo1, lo2
+ // The following can be improved, but not that much.
+ SDOperand Tmp1, Tmp2, Tmp3;
+ Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETEQ);
+ Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, CCCode);
+ Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
+ Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETNE);
+ Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, CCCode);
+ Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
+ NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3);
+ NewRHS = SDOperand(); // LHS is the result, not a compare.
+ return;
+ }
+
+
+ if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) {
+ if (RHSLo == RHSHi)
+ if (ConstantSDNode *RHSCST = dyn_cast(RHSLo))
+ if (RHSCST->isAllOnesValue()) {
+ // Equality comparison to -1.
+ NewLHS = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi);
+ NewRHS = RHSLo;
+ return;
+ }
+
+ NewLHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo);
+ NewRHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi);
+ NewLHS = DAG.getNode(ISD::OR, NewLHS.getValueType(), NewLHS, NewRHS);
+ NewRHS = DAG.getConstant(0, NewLHS.getValueType());
+ return;
+ }
+
+ // If this is a comparison of the sign bit, just look at the top part.
+ // X > -1, x < 0
+ if (ConstantSDNode *CST = dyn_cast(NewRHS))
+ if ((CCCode == ISD::SETLT && CST->getValue() == 0) || // X < 0
+ (CCCode == ISD::SETGT && CST->isAllOnesValue())) { // X > -1
+ NewLHS = LHSHi;
+ NewRHS = RHSHi;
+ return;
+ }
+
+ // FIXME: This generated code sucks.
+ ISD::CondCode LowCC;
+ switch (CCCode) {
+ default: assert(0 && "Unknown integer setcc!");
+ case ISD::SETLT:
+ case ISD::SETULT: LowCC = ISD::SETULT; break;
+ case ISD::SETGT:
+ case ISD::SETUGT: LowCC = ISD::SETUGT; break;
+ case ISD::SETLE:
+ case ISD::SETULE: LowCC = ISD::SETULE; break;
+ case ISD::SETGE:
+ case ISD::SETUGE: LowCC = ISD::SETUGE; break;
+ }
+
+ // Tmp1 = lo(op1) < lo(op2) // Always unsigned comparison
+ // Tmp2 = hi(op1) < hi(op2) // Signedness depends on operands
+ // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2;
+
+ // NOTE: on targets without efficient SELECT of bools, we can always use
+ // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
+ TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL);
+ SDOperand Tmp1, Tmp2;
+ Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, LowCC,
+ false, DagCombineInfo);
+ if (!Tmp1.Val)
+ Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, LowCC);
+ Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi,
+ CCCode, false, DagCombineInfo);
+ if (!Tmp2.Val)
+ Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), LHSHi, RHSHi,
+ DAG.getCondCode(CCCode));
+
+ ConstantSDNode *Tmp1C = dyn_cast(Tmp1.Val);
+ ConstantSDNode *Tmp2C = dyn_cast(Tmp2.Val);
+ if ((Tmp1C && Tmp1C->getValue() == 0) ||
+ (Tmp2C && Tmp2C->getValue() == 0 &&
+ (CCCode == ISD::SETLE || CCCode == ISD::SETGE ||
+ CCCode == ISD::SETUGE || CCCode == ISD::SETULE)) ||
+ (Tmp2C && Tmp2C->getValue() == 1 &&
+ (CCCode == ISD::SETLT || CCCode == ISD::SETGT ||
+ CCCode == ISD::SETUGT || CCCode == ISD::SETULT))) {
+ // low part is known false, returns high part.
+ // For LE / GE, if high part is known false, ignore the low part.
+ // For LT / GT, if high part is known true, ignore the low part.
+ NewLHS = Tmp2;
+ NewRHS = SDOperand();
+ return;
+ }
+
+ NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi,
+ ISD::SETEQ, false, DagCombineInfo);
+ if (!NewLHS.Val)
+ NewLHS = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETEQ);
+ NewLHS = DAG.getNode(ISD::SELECT, Tmp1.getValueType(),
+ NewLHS, Tmp1, Tmp2);
+ NewRHS = SDOperand();
+}
+
+
+SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) {
+ assert(OpNo == 1 && "Can only expand the stored value so far");
+ assert(!N->isTruncatingStore() && "Can't expand truncstore!");
+
+ unsigned IncrementSize = 0;
+ SDOperand Lo, Hi;
+
+ // If this is a vector type, then we have to calculate the increment as
+ // the product of the element size in bytes, and the number of elements
+ // in the high half of the vector.
+ if (MVT::isVector(N->getValue().getValueType())) {
+ assert(0 && "Vectors not supported yet");
+#if 0
+ SDNode *InVal = ST->getValue().Val;
+ unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0));
+ MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0));
+
+ // Figure out if there is a simple type corresponding to this Vector
+ // type. If so, convert to the vector type.
+ MVT::ValueType TVT = MVT::getVectorType(EVT, NumElems);
+ if (TLI.isTypeLegal(TVT)) {
+ // Turn this into a normal store of the vector type.
+ Tmp3 = LegalizeOp(Node->getOperand(1));
+ Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ SVOffset, isVolatile, Alignment);
+ Result = LegalizeOp(Result);
+ break;
+ } else if (NumElems == 1) {
+ // Turn this into a normal store of the scalar type.
+ Tmp3 = ScalarizeVectorOp(Node->getOperand(1));
+ Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ SVOffset, isVolatile, Alignment);
+ // The scalarized value type may not be legal, e.g. it might require
+ // promotion or expansion. Relegalize the scalar store.
+ return LegalizeOp(Result);
+ } else {
+ SplitVectorOp(Node->getOperand(1), Lo, Hi);
+ IncrementSize = NumElems/2 * MVT::getSizeInBits(EVT)/8;
+ }
+#endif
+ } else {
+ GetExpandedOp(N->getValue(), Lo, Hi);
+ IncrementSize = Hi.Val ? MVT::getSizeInBits(Hi.getValueType())/8 : 0;
+
+ if (!TLI.isLittleEndian())
+ std::swap(Lo, Hi);
+ }
+
+ SDOperand Chain = N->getChain();
+ SDOperand Ptr = N->getBasePtr();
+ int SVOffset = N->getSrcValueOffset();
+ unsigned Alignment = N->getAlignment();
+ bool isVolatile = N->isVolatile();
+
+ Lo = DAG.getStore(Chain, Lo, Ptr, N->getSrcValue(),
+ SVOffset, isVolatile, Alignment);
+
+ assert(Hi.Val && "FIXME: int <-> float should be handled with promote!");
+#if 0
+ if (Hi.Val == NULL) {
+ // Must be int <-> float one-to-one expansion.
+ return Lo;
+ }
+#endif
+
+ Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ getIntPtrConstant(IncrementSize));
+ assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!");
+ Hi = DAG.getStore(Chain, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
+ isVolatile, std::max(Alignment, IncrementSize));
+ return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+}
+
+//===----------------------------------------------------------------------===//
+// Entry Point
+//===----------------------------------------------------------------------===//
+
+/// LegalizeTypes - This transforms the SelectionDAG into a SelectionDAG that
+/// only uses types natively supported by the target.
+///
+/// Note that this is an involved process that may invalidate pointers into
+/// the graph.
+void SelectionDAG::LegalizeTypes() {
+ DAGTypeLegalizer(*this).run();
+}
+
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=42981&r1=42980&r2=42981&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Oct 15 01:10:22 2007
@@ -422,14 +422,12 @@
N = NewNodes[1];
SDNode *LoadNode = NewNodes[0];
- std::vector Deleted;
unsigned NumVals = N->getNumValues();
unsigned OldNumVals = SU->Node->getNumValues();
for (unsigned i = 0; i != NumVals; ++i)
- DAG.ReplaceAllUsesOfValueWith(SDOperand(SU->Node, i),
- SDOperand(N, i), Deleted);
+ DAG.ReplaceAllUsesOfValueWith(SDOperand(SU->Node, i), SDOperand(N, i));
DAG.ReplaceAllUsesOfValueWith(SDOperand(SU->Node, OldNumVals-1),
- SDOperand(LoadNode, 1), Deleted);
+ SDOperand(LoadNode, 1));
SUnit *LoadSU = NewSUnit(LoadNode);
SUnit *NewSU = NewSUnit(N);
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=42981&r1=42980&r2=42981&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Oct 15 01:10:22 2007
@@ -3232,11 +3232,11 @@
/// uses of other values produced by From.Val alone. The Deleted vector is
/// handled the same was as for ReplaceAllUsesWith.
void SelectionDAG::ReplaceAllUsesOfValueWith(SDOperand From, SDOperand To,
- std::vector &Deleted) {
+ std::vector *Deleted) {
assert(From != To && "Cannot replace a value with itself");
// Handle the simple, trivial, case efficiently.
if (From.Val->getNumValues() == 1 && To.Val->getNumValues() == 1) {
- ReplaceAllUsesWith(From, To, &Deleted);
+ ReplaceAllUsesWith(From, To, Deleted);
return;
}
@@ -3244,48 +3244,66 @@
// deterministically ordered and uniqued set, so we use a SmallSetVector.
SmallSetVector Users(From.Val->use_begin(), From.Val->use_end());
+ std::vector LocalDeletionVector;
+
+ // Pick a deletion vector to use. If the user specified one, use theirs,
+ // otherwise use a local one.
+ std::vector *DeleteVector = Deleted ? Deleted : &LocalDeletionVector;
while (!Users.empty()) {
// We know that this user uses some value of From. If it is the right
// value, update it.
SDNode *User = Users.back();
Users.pop_back();
- for (SDOperand *Op = User->OperandList,
- *E = User->OperandList+User->NumOperands; Op != E; ++Op) {
+ // Scan for an operand that matches From.
+ SDOperand *Op = User->OperandList, *E = User->OperandList+User->NumOperands;
+ for (; Op != E; ++Op)
+ if (*Op == From) break;
+
+ // If there are no matches, the user must use some other result of From.
+ if (Op == E) continue;
+
+ // Okay, we know this user needs to be updated. Remove its old self
+ // from the CSE maps.
+ RemoveNodeFromCSEMaps(User);
+
+ // Update all operands that match "From".
+ for (; Op != E; ++Op) {
if (*Op == From) {
- // Okay, we know this user needs to be updated. Remove its old self
- // from the CSE maps.
- RemoveNodeFromCSEMaps(User);
-
- // Update all operands that match "From".
- for (; Op != E; ++Op) {
- if (*Op == From) {
- From.Val->removeUser(User);
- *Op = To;
- To.Val->addUser(User);
- }
- }
-
- // Now that we have modified User, add it back to the CSE maps. If it
- // already exists there, recursively merge the results together.
- if (SDNode *Existing = AddNonLeafNodeToCSEMaps(User)) {
- unsigned NumDeleted = Deleted.size();
- ReplaceAllUsesWith(User, Existing, &Deleted);
-
- // User is now dead.
- Deleted.push_back(User);
- DeleteNodeNotInCSEMaps(User);
-
- // We have to be careful here, because ReplaceAllUsesWith could have
- // deleted a user of From, which means there may be dangling pointers
- // in the "Users" setvector. Scan over the deleted node pointers and
- // remove them from the setvector.
- for (unsigned i = NumDeleted, e = Deleted.size(); i != e; ++i)
- Users.remove(Deleted[i]);
- }
- break; // Exit the operand scanning loop.
+ From.Val->removeUser(User);
+ *Op = To;
+ To.Val->addUser(User);
}
}
+
+ // Now that we have modified User, add it back to the CSE maps. If it
+ // already exists there, recursively merge the results together.
+ SDNode *Existing = AddNonLeafNodeToCSEMaps(User);
+ if (!Existing) continue; // Continue on to next user.
+
+ // If there was already an existing matching node, use ReplaceAllUsesWith
+ // to replace the dead one with the existing one. However, this can cause
+ // recursive merging of other unrelated nodes down the line. The merging
+ // can cause deletion of nodes that used the old value. In this case,
+ // we have to be certain to remove them from the Users set.
+ unsigned NumDeleted = DeleteVector->size();
+ ReplaceAllUsesWith(User, Existing, DeleteVector);
+
+ // User is now dead.
+ DeleteVector->push_back(User);
+ DeleteNodeNotInCSEMaps(User);
+
+ // We have to be careful here, because ReplaceAllUsesWith could have
+ // deleted a user of From, which means there may be dangling pointers
+ // in the "Users" setvector. Scan over the deleted node pointers and
+ // remove them from the setvector.
+ for (unsigned i = NumDeleted, e = DeleteVector->size(); i != e; ++i)
+ Users.remove((*DeleteVector)[i]);
+
+ // If the user doesn't need the set of deleted elements, don't retain them
+ // to the next loop iteration.
+ if (Deleted == 0)
+ LocalDeletionVector.clear();
}
}
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=42981&r1=42980&r2=42981&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Oct 15 01:10:22 2007
@@ -4714,6 +4714,10 @@
// Second step, hack on the DAG until it only uses operations and types that
// the target supports.
+#if 0 // Enable this some day.
+ DAG.LegalizeTypes();
+ // Someday even later, enable a dag combine pass here.
+#endif
DAG.Legalize();
DOUT << "Legalized selection DAG:\n";
Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=42981&r1=42980&r2=42981&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Mon Oct 15 01:10:22 2007
@@ -3939,7 +3939,7 @@
OS << "}\n\n";
OS << "void ReplaceUses(SDOperand F, SDOperand T) DISABLE_INLINE {\n";
- OS << " CurDAG->ReplaceAllUsesOfValueWith(F, T, ISelKilled);\n";
+ OS << " CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISelKilled);\n";
OS << " setSelected(F.Val->getNodeId());\n";
OS << " RemoveKilled();\n";
OS << "}\n";
@@ -3950,7 +3950,7 @@
OS << " for (unsigned i = 0, e = std::min(FNumVals, TNumVals); "
<< "i < e; ++i)\n";
OS << " CurDAG->ReplaceAllUsesOfValueWith(SDOperand(F, i), "
- << "SDOperand(T, i), ISelKilled);\n";
+ << "SDOperand(T, i), &ISelKilled);\n";
OS << " } else {\n";
OS << " CurDAG->ReplaceAllUsesWith(F, T, &ISelKilled);\n";
OS << " }\n";
From baldrick at free.fr Mon Oct 15 07:01:43 2007
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 15 Oct 2007 14:01:43 +0200
Subject: [llvm-commits] [llvm] r42981 - in /llvm/trunk:
include/llvm/CodeGen/SelectionDAG.h
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
utils/TableGen/DAGISelEmitter.cpp
In-Reply-To: <200710150610.l9F6ANV3030436@zion.cs.uiuc.edu>
References: <200710150610.l9F6ANV3030436@zion.cs.uiuc.edu>
Message-ID: <200710151401.46887.baldrick@free.fr>
Hi Chris, this sounds like a big improvement! Where did you find the time
to do this?!
A few comments.
> 1. When finished, this will *significantly* reduce the amount of code in
> LegalizeDAG.cpp. It will remove all the code related to promotion and
> expansion as well as splitting and scalarizing vectors.
Yay!
> 2. SoftFP is a mess, I need to talk to Evan about it.
Presumably f64 will be promoted to i64 then possibly expanded into 2xi32,
rather than mulching the two steps together in expand as is done now. Codegen
support for arbitrary precision integers also needs to promote to a type which
is then expanded. Does your new infrastructure support this (currently expand
is only allowed to follow expand, not promote)? Dunno if it's useful to support
promote following promote/expand - I don't have a use for it, and forbidding
it would help prevent infinite promote/expand loops.
> 5. The code nicely separates out handling of operations with invalid
> results from operations with invalid operands, making some cases
> simpler and easier to understand.
Yay!
The following two comments seem contradictory. The first one suggests
that operations are not legalized...
> ... This legalizer is designed to run before the
> operation legalizer and ensure just that the input dag is transformed
> into an output dag whose operand and result types are all legal, even
> if the operations on those types are not.
While here it sounds like operations are legalized...
> +/// DAGTypeLegalizer - This takes an arbitrary SelectionDAG as input and
> +/// hacks on it until the target machine can handle it. This involves
> +/// eliminating value sizes the machine cannot handle (promoting small sizes to
> +/// large sizes or splitting up large values into small values) as well as
> +/// eliminating operations the machine cannot handle.
> + enum LegalizeAction {
> + Legal, // The target natively supports this operation.
-> The target natively supports this type.
> + Promote, // This operation should be executed in a larger type.
-> This type should be replaced with a larger type.
> + Expand // Try to expand this to other ops, otherwise use a libcall.
-> This type should be split into two types of half the size.
> + /// ValueTypeActions - This is a bitvector that contains two bits for each
> + /// value type, where the two bits correspond to the LegalizeAction enum.
value type -> simple value type
That said, I will work on adding support for extended value types myself, so I
won't mention extended value types in the result of this email.
By the way the logic supposes that the result of any node is an operand for
some other node. Is at least one result always used?
> + // If the node needs revisitation, don't add all users to the worklist etc.
revisitation -> revisiting
Or is this a technical term? It's used several times.
> +SDOperand DAGTypeLegalizer::PromoteResult_TRUNCATE(SDNode *N) {
> + MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
> + switch (getTypeAction(N->getOperand(0).getValueType())) {
Presumably this switch is redundant, because it must be Promote,
and you just didn't get around to cleaning it up yet?
Ciao,
Duncan.
From baldrick at free.fr Mon Oct 15 08:30:19 2007
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 15 Oct 2007 13:30:19 -0000
Subject: [llvm-commits] [llvm] r42982 -
/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
Message-ID: <200710151330.l9FDUJeG023133@zion.cs.uiuc.edu>
Author: baldrick
Date: Mon Oct 15 08:30:18 2007
New Revision: 42982
URL: http://llvm.org/viewvc/llvm-project?rev=42982&view=rev
Log:
Fix some typos. Call getTypeToTransformTo rather than
getTypeToExpandTo. The difference is that
getTypeToExpandTo gives the final result of expansion
(eg: i128 -> i32 on a 32 bit machine) while
getTypeToTransformTo does just one step (i128 -> i64).
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=42982&r1=42981&r2=42982&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Mon Oct 15 08:30:18 2007
@@ -61,8 +61,8 @@
};
/// ValueTypeActions - This is a bitvector that contains two bits for each
- /// value type, where the two bits correspond to the LegalizeAction enum.
- /// This can be queried with "getTypeAction(VT)".
+ /// simple value type, where the two bits correspond to the LegalizeAction
+ /// enum. This can be queried with "getTypeAction(VT)".
TargetLowering::ValueTypeActionImpl ValueTypeActions;
/// getTypeAction - Return how we should legalize values of this type, either
@@ -87,7 +87,7 @@
DenseMap PromotedNodes;
/// ExpandedNodes - For nodes that need to be expanded this map indicates
- /// which which operands are the expanded version of the input.
+ /// which operands are the expanded version of the input.
DenseMap > ExpandedNodes;
/// Worklist - This defines a worklist of nodes to process. In order to be
@@ -190,7 +190,7 @@
DAG.setRoot(SDOperand());
// Walk all nodes in the graph, assigning them a NodeID of 'ReadyToProcess'
- // (and remembering them) if they are leafs and assigning 'NewNode' if
+ // (and remembering them) if they are leaves and assigning 'NewNode' if
// non-leaves.
for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
E = DAG.allnodes_end(); I != E; ++I) {
@@ -416,7 +416,7 @@
/// PromoteResult - This method is called when a result of a node is found to be
/// in need of promotion to a larger type. At this point, the node may also
/// have invalid operands or may have other results that need expansion, we just
-/// know that (at least) the one result needs promotion.
+/// know that (at least) one result needs promotion.
void DAGTypeLegalizer::PromoteResult(SDNode *N, unsigned ResNo) {
DEBUG(cerr << "Promote node result: "; N->dump(&DAG); cerr << "\n");
SDOperand Result = SDOperand();
@@ -556,7 +556,7 @@
/// ExpandResult - This method is called when the specified result of the
/// specified node is found to need expansion. At this point, the node may also
/// have invalid operands or may have other results that need promotion, we just
-/// know that (at least) the one result needs expansion.
+/// know that (at least) one result needs expansion.
void DAGTypeLegalizer::ExpandResult(SDNode *N, unsigned ResNo) {
DEBUG(cerr << "Expand node result: "; N->dump(&DAG); cerr << "\n");
SDOperand Lo, Hi;
@@ -599,13 +599,13 @@
void DAGTypeLegalizer::ExpandResult_UNDEF(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
- MVT::ValueType NVT = TLI.getTypeToExpandTo(N->getValueType(0));
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
Lo = Hi = DAG.getNode(ISD::UNDEF, NVT);
}
void DAGTypeLegalizer::ExpandResult_Constant(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
- MVT::ValueType NVT = TLI.getTypeToExpandTo(N->getValueType(0));
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
uint64_t Cst = cast(N)->getValue();
Lo = DAG.getConstant(Cst, NVT);
Hi = DAG.getConstant(Cst >> MVT::getSizeInBits(NVT), NVT);
@@ -621,7 +621,7 @@
void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
- MVT::ValueType NVT = TLI.getTypeToExpandTo(N->getValueType(0));
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
// The low part is any extension of the input (which degenerates to a copy).
Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, N->getOperand(0));
Hi = DAG.getNode(ISD::UNDEF, NVT); // The high part is undefined.
@@ -629,7 +629,7 @@
void DAGTypeLegalizer::ExpandResult_ZERO_EXTEND(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
- MVT::ValueType NVT = TLI.getTypeToExpandTo(N->getValueType(0));
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
// The low part is zero extension of the input (which degenerates to a copy).
Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0));
Hi = DAG.getConstant(0, NVT); // The high part is just a zero.
@@ -637,7 +637,7 @@
void DAGTypeLegalizer::ExpandResult_SIGN_EXTEND(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
- MVT::ValueType NVT = TLI.getTypeToExpandTo(N->getValueType(0));
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
// The low part is sign extension of the input (which degenerates to a copy).
Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0));
@@ -651,7 +651,7 @@
void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N,
SDOperand &Lo, SDOperand &Hi) {
MVT::ValueType VT = N->getValueType(0);
- MVT::ValueType NVT = TLI.getTypeToExpandTo(VT);
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(VT);
SDOperand Ch = N->getChain(); // Legalize the chain.
SDOperand Ptr = N->getBasePtr(); // Legalize the pointer.
ISD::LoadExtType ExtType = N->getExtensionType();
@@ -816,7 +816,7 @@
void DAGTypeLegalizer::ExpandResult_MUL(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
MVT::ValueType VT = N->getValueType(0);
- MVT::ValueType NVT = TLI.getTypeToExpandTo(VT);
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(VT);
// If the target wants to custom expand this, let them.
if (TLI.getOperationAction(ISD::MUL, VT) == TargetLowering::Custom) {
@@ -941,7 +941,7 @@
// Next check to see if the target supports this SHL_PARTS operation or if it
// will custom expand it.
- MVT::ValueType NVT = TLI.getTypeToExpandTo(VT);
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(VT);
TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT);
if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
Action == TargetLowering::Custom) {
From baldrick at free.fr Mon Oct 15 09:19:05 2007
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 15 Oct 2007 16:19:05 +0200
Subject: [llvm-commits] [llvm] r42981 - in /llvm/trunk:
include/llvm/CodeGen/SelectionDAG.h
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
utils/TableGen/DAGISelEmitter.cpp
In-Reply-To: <200710151401.46887.baldrick@free.fr>
References: <200710150610.l9F6ANV3030436@zion.cs.uiuc.edu>
<200710151401.46887.baldrick@free.fr>
Message-ID: <200710151619.05947.baldrick@free.fr>
> > +SDOperand DAGTypeLegalizer::PromoteResult_TRUNCATE(SDNode *N) {
> > + MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
> > + switch (getTypeAction(N->getOperand(0).getValueType())) {
>
> Presumably this switch is redundant, because it must be Promote,
> and you just didn't get around to cleaning it up yet?
Please ignore this, I understand how it works now.
Ciao,
Duncan.
From neil at daikokuya.co.uk Mon Oct 15 10:00:55 2007
From: neil at daikokuya.co.uk (Neil Booth)
Date: Mon, 15 Oct 2007 15:00:55 -0000
Subject: [llvm-commits] [llvm] r42984 - /llvm/trunk/lib/Support/APFloat.cpp
Message-ID: <200710151500.l9FF0udn028071@zion.cs.uiuc.edu>
Author: neil
Date: Mon Oct 15 10:00:55 2007
New Revision: 42984
URL: http://llvm.org/viewvc/llvm-project?rev=42984&view=rev
Log:
Fast-track obviously over-large and over-small exponents during decimal->
integer conversion. In some such cases this makes us one or two orders
of magnitude faster than NetBSD's libc. Glibc seems to have a similar
fast path.
Also, tighten up some upper bounds to save a bit of memory.
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=42984&r1=42983&r2=42984&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APFloat.cpp (original)
+++ llvm/trunk/lib/Support/APFloat.cpp Mon Oct 15 10:00:55 2007
@@ -59,7 +59,7 @@
/* A tight upper bound on number of parts required to hold the value
pow(5, power) is
- power * 1024 / (441 * integerPartWidth) + 1
+ power * 815 / (351 * integerPartWidth) + 1
However, whilst the result may require only this many parts,
because we are multiplying two values to get it, the
@@ -70,8 +70,8 @@
const unsigned int maxExponent = 16383;
const unsigned int maxPrecision = 113;
const unsigned int maxPowerOfFiveExponent = maxExponent + maxPrecision - 1;
- const unsigned int maxPowerOfFiveParts = 2 + ((maxPowerOfFiveExponent * 1024)
- / (441 * integerPartWidth));
+ const unsigned int maxPowerOfFiveParts = 2 + ((maxPowerOfFiveExponent * 815)
+ / (351 * integerPartWidth));
}
/* Put a bunch of private, handy routines in an anonymous namespace. */
@@ -226,12 +226,19 @@
dddd.dddd[eE][+-]ddd
where the decimal point and exponent are optional, fill out the
- structure D. If the value is zero, V->firstSigDigit
- points to a zero, and the return exponent is zero. */
+ structure D. Exponent is appropriate if the significand is
+ treated as an integer, and normalizedExponent if the significand
+ is taken to have the decimal point after a single leading
+ non-zero digit.
+
+ If the value is zero, V->firstSigDigit points to a zero, and the
+ return exponent is zero.
+ */
struct decimalInfo {
const char *firstSigDigit;
const char *lastSigDigit;
int exponent;
+ int normalizedExponent;
};
void
@@ -243,6 +250,7 @@
D->firstSigDigit = p;
D->exponent = 0;
+ D->normalizedExponent = 0;
for (;;) {
if (*p == '.') {
@@ -270,8 +278,10 @@
while (*p == '0');
while (*p == '.');
- /* Adjust the specified exponent for any decimal point. */
+ /* Adjust the exponents for any decimal point. */
D->exponent += (dot - p) - (dot > p);
+ D->normalizedExponent = (D->exponent + (p - D->firstSigDigit)
+ - (dot > D->firstSigDigit && dot < p));
}
D->lastSigDigit = p;
@@ -2079,19 +2089,45 @@
/* Scan the text. */
interpretDecimal(p, &D);
+ /* Handle the quick cases. First the case of no significant digits,
+ i.e. zero, and then exponents that are obviously too large or too
+ small. Writing L for log 10 / log 2, a number d.ddddd*10^exp
+ definitely overflows if
+
+ (exp - 1) * L >= maxExponent
+
+ and definitely underflows to zero where
+
+ (exp + 1) * L <= minExponent - precision
+
+ With integer arithmetic the tightest bounds for L are
+
+ 93/28 < L < 196/59 [ numerator <= 256 ]
+ 42039/12655 < L < 28738/8651 [ numerator <= 65536 ]
+ */
+
if (*D.firstSigDigit == '0') {
category = fcZero;
fs = opOK;
+ } else if ((D.normalizedExponent + 1) * 28738
+ <= 8651 * (semantics->minExponent - (int) semantics->precision)) {
+ /* Underflow to zero and round. */
+ zeroSignificand();
+ fs = normalize(rounding_mode, lfLessThanHalf);
+ } else if ((D.normalizedExponent - 1) * 42039
+ >= 12655 * semantics->maxExponent) {
+ /* Overflow and round. */
+ fs = handleOverflow(rounding_mode);
} else {
integerPart *decSignificand;
unsigned int partCount;
/* A tight upper bound on number of bits required to hold an
- N-digit decimal integer is N * 256 / 77. Allocate enough space
+ N-digit decimal integer is N * 196 / 59. Allocate enough space
to hold the full significand, and an extra part required by
tcMultiplyPart. */
partCount = (D.lastSigDigit - D.firstSigDigit) + 1;
- partCount = partCountForBits(1 + 256 * partCount / 77);
+ partCount = partCountForBits(1 + 196 * partCount / 59);
decSignificand = new integerPart[partCount + 1];
partCount = 0;
From dpatel at apple.com Mon Oct 15 10:31:35 2007
From: dpatel at apple.com (Devang Patel)
Date: Mon, 15 Oct 2007 15:31:35 -0000
Subject: [llvm-commits] [llvm] r42985 -
/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
Message-ID: <200710151531.l9FFVZpF029764@zion.cs.uiuc.edu>
Author: dpatel
Date: Mon Oct 15 10:31:35 2007
New Revision: 42985
URL: http://llvm.org/viewvc/llvm-project?rev=42985&view=rev
Log:
Achieve same result but use fewer lines of code.
Modified:
llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=42985&r1=42984&r2=42985&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Oct 15 10:31:35 2007
@@ -7674,14 +7674,13 @@
unsigned Align = cast(CI.getOperand(4))->getZExtValue();
PointerType *NewPtrTy = NULL;
// Destination pointer type is always i8 *
- if (Size == 8)
- NewPtrTy = PointerType::get(Type::Int64Ty);
- else if (Size == 4)
- NewPtrTy = PointerType::get(Type::Int32Ty);
- else if (Size == 2)
- NewPtrTy = PointerType::get(Type::Int16Ty);
- else if (Size == 1)
- NewPtrTy = PointerType::get(Type::Int8Ty);
+ // If Size is 8 then use Int64Ty
+ // If Size is 4 then use Int32Ty
+ // If Size is 2 then use Int16Ty
+ // If Size is 1 then use Int8Ty
+ if (Size && Size <=8 && !(Size&(Size-1)))
+ NewPtrTy = PointerType::get(IntegerType::get(Size<<3));
+
if (NewPtrTy) {
Value *Src = InsertCastBefore(Instruction::BitCast, CI.getOperand(2), NewPtrTy, CI);
Value *Dest = InsertCastBefore(Instruction::BitCast, CI.getOperand(1), NewPtrTy, CI);
From dpatel at apple.com Mon Oct 15 10:41:07 2007
From: dpatel at apple.com (Devang Patel)
Date: Mon, 15 Oct 2007 15:41:07 -0000
Subject: [llvm-commits] [llvm] r42986 -
/llvm/trunk/test/CFrontend/2007-10-15-VoidPtr.c
Message-ID: <200710151541.l9FFf7KM030418@zion.cs.uiuc.edu>
Author: dpatel
Date: Mon Oct 15 10:41:07 2007
New Revision: 42986
URL: http://llvm.org/viewvc/llvm-project?rev=42986&view=rev
Log:
New test.
Added:
llvm/trunk/test/CFrontend/2007-10-15-VoidPtr.c
Added: llvm/trunk/test/CFrontend/2007-10-15-VoidPtr.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/2007-10-15-VoidPtr.c?rev=42986&view=auto
==============================================================================
--- llvm/trunk/test/CFrontend/2007-10-15-VoidPtr.c (added)
+++ llvm/trunk/test/CFrontend/2007-10-15-VoidPtr.c Mon Oct 15 10:41:07 2007
@@ -0,0 +1,5 @@
+// RUN: llvm-gcc -S %s -o /dev/null
+void bork(void **data) {
+ (*(unsigned short *) (&(data[37])[927]) = 0);
+}
+
From dpatel at apple.com Mon Oct 15 10:41:50 2007
From: dpatel at apple.com (Devang Patel)
Date: Mon, 15 Oct 2007 15:41:50 -0000
Subject: [llvm-commits] [llvm-gcc-4.0] r42987 - in /llvm-gcc-4.0/trunk/gcc:
llvm-convert.cpp llvm-types.cpp
Message-ID: <200710151541.l9FFfoLV030502@zion.cs.uiuc.edu>
Author: dpatel
Date: Mon Oct 15 10:41:50 2007
New Revision: 42987
URL: http://llvm.org/viewvc/llvm-project?rev=42987&view=rev
Log:
Fix
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20071015/054529.html
Modified:
llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp
llvm-gcc-4.0/trunk/gcc/llvm-types.cpp
Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp?rev=42987&r1=42986&r2=42987&view=diff
==============================================================================
--- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Mon Oct 15 10:41:50 2007
@@ -5288,13 +5288,21 @@
// float foo(int w, float A[][w], int g) { return A[g][0]; }
ArrayAddr = BitCastToType(ArrayAddr, PointerType::get(Type::Int8Ty));
- Value *TypeSize = Emit(array_ref_element_size(exp), 0);
- TypeSize = CastToUIntType(TypeSize, IntPtrTy);
+ Value *TypeSize = NULL;
+ if (VOID_TYPE_P(TREE_TYPE(ArrayType))) {
+ // void * size is 1
+ Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
+ return BitCastToType(Ptr, PointerType::get(Type::Int8Ty));
+ }
+ else {
+ TypeSize = Emit(array_ref_element_size(exp), 0);
+ TypeSize = CastToUIntType(TypeSize, IntPtrTy);
+ IndexVal = Builder.CreateMul(IndexVal, TypeSize, "tmp");
+ Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
+ return BitCastToType(Ptr, PointerType::get(ConvertType(TREE_TYPE(exp))));
+ }
- IndexVal = Builder.CreateMul(IndexVal, TypeSize, "tmp");
- Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
- return BitCastToType(Ptr, PointerType::get(ConvertType(TREE_TYPE(exp))));
}
/// getFieldOffsetInBits - Return the offset (in bits) of a FIELD_DECL in a
Modified: llvm-gcc-4.0/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-types.cpp?rev=42987&r1=42986&r2=42987&view=diff
==============================================================================
--- llvm-gcc-4.0/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Mon Oct 15 10:41:50 2007
@@ -303,7 +303,7 @@
TREE_CODE (type) == REFERENCE_TYPE) && "not a sequential type!");
// This relies on gcc types with constant size mapping to LLVM types with the
// same size.
- return isInt64(TYPE_SIZE(TREE_TYPE(type)), true);
+ return !VOID_TYPE_P(TREE_TYPE(type)) && isInt64(TYPE_SIZE(TREE_TYPE(type)), true);
}
/// isArrayCompatible - Return true if the specified gcc array or pointer type
From dpatel at apple.com Mon Oct 15 11:00:25 2007
From: dpatel at apple.com (Devang Patel)
Date: Mon, 15 Oct 2007 16:00:25 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r42988 -
/llvm-gcc-4.2/trunk/gcc/config.gcc
Message-ID: <200710151600.l9FG0PUC031348@zion.cs.uiuc.edu>
Author: dpatel
Date: Mon Oct 15 11:00:25 2007
New Revision: 42988
URL: http://llvm.org/viewvc/llvm-project?rev=42988&view=rev
Log:
Remove c style comment.
Modified:
llvm-gcc-4.2/trunk/gcc/config.gcc
Modified: llvm-gcc-4.2/trunk/gcc/config.gcc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config.gcc?rev=42988&r1=42987&r2=42988&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config.gcc (original)
+++ llvm-gcc-4.2/trunk/gcc/config.gcc Mon Oct 15 11:00:25 2007
@@ -1040,7 +1040,6 @@
# Deleted a comment here.
# APPLE LOCAL mainline
with_cpu=${with_cpu:-core2}
- /* APPLE LOCAL Macintosh alignment 2002-2-19 --ff */
extra_options="${extra_options} i386/darwin.opt"
# APPLE LOCAL 4099000
tmake_file="${tmake_file} i386/t-darwin"
From dpatel at apple.com Mon Oct 15 11:01:09 2007
From: dpatel at apple.com (Devang Patel)
Date: Mon, 15 Oct 2007 16:01:09 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r42989 - in /llvm-gcc-4.2/trunk:
configure configure.in
Message-ID: <200710151601.l9FG194m031388@zion.cs.uiuc.edu>
Author: dpatel
Date: Mon Oct 15 11:01:08 2007
New Revision: 42989
URL: http://llvm.org/viewvc/llvm-project?rev=42989&view=rev
Log:
Do not build libobjc on darwin.
Modified:
llvm-gcc-4.2/trunk/configure
llvm-gcc-4.2/trunk/configure.in
Modified: llvm-gcc-4.2/trunk/configure
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/configure?rev=42989&r1=42988&r2=42989&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/configure (original)
+++ llvm-gcc-4.2/trunk/configure Mon Oct 15 11:01:08 2007
@@ -1216,6 +1216,8 @@
noconfigdirs="$noconfigdirs ld gas gdb gprof"
noconfigdirs="$noconfigdirs sim target-rda"
noconfigdirs="$noconfigdirs ${libgcj} target-libstdc++-v3"
+ # LLVM LOCAL
+ noconfigdirs="$noconfigdirs target-libobjc"
;;
*-*-freebsd[12] | *-*-freebsd[12].* | *-*-freebsd*aout*)
noconfigdirs="$noconfigdirs target-newlib target-libgloss ${libgcj}"
@@ -1870,7 +1872,7 @@
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1874: checking for $ac_word" >&5
+echo "configure:1876: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1900,7 +1902,7 @@
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1904: checking for $ac_word" >&5
+echo "configure:1906: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1951,7 +1953,7 @@
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1955: checking for $ac_word" >&5
+echo "configure:1957: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1983,7 +1985,7 @@
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1987: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1989: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -1994,12 +1996,12 @@
cat > conftest.$ac_ext << EOF
-#line 1998 "configure"
+#line 2000 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
-if { (eval echo configure:2003: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2005: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
@@ -2025,12 +2027,12 @@
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:2029: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:2031: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:2034: checking whether we are using GNU C" >&5
+echo "configure:2036: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2039,7 +2041,7 @@
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2043: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2045: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
@@ -2058,7 +2060,7 @@
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:2062: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:2064: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2125,7 +2127,7 @@
# Extract the first word of "${ac_tool_prefix}gnatbind", so it can be a program name with args.
set dummy ${ac_tool_prefix}gnatbind; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2129: checking for $ac_word" >&5
+echo "configure:2131: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_GNATBIND'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2157,7 +2159,7 @@
# Extract the first word of "gnatbind", so it can be a program name with args.
set dummy gnatbind; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2161: checking for $ac_word" >&5
+echo "configure:2163: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_GNATBIND'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2190,7 +2192,7 @@
fi
echo $ac_n "checking whether compiler driver understands Ada""... $ac_c" 1>&6
-echo "configure:2194: checking whether compiler driver understands Ada" >&5
+echo "configure:2196: checking whether compiler driver understands Ada" >&5
if eval "test \"`echo '$''{'acx_cv_cc_gcc_supports_ada'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2222,7 +2224,7 @@
fi
echo $ac_n "checking how to compare bootstrapped objects""... $ac_c" 1>&6
-echo "configure:2226: checking how to compare bootstrapped objects" >&5
+echo "configure:2228: checking how to compare bootstrapped objects" >&5
if eval "test \"`echo '$''{'gcc_cv_prog_cmp_skip'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2342,9 +2344,9 @@
CFLAGS="$CFLAGS $gmpinc"
# Check GMP actually works
echo $ac_n "checking for correct version of gmp.h""... $ac_c" 1>&6
-echo "configure:2346: checking for correct version of gmp.h" >&5
+echo "configure:2348: checking for correct version of gmp.h" >&5
cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2361: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
echo "$ac_t""yes" 1>&6
else
@@ -2368,9 +2370,9 @@
if test x"$have_gmp" = xyes; then
echo $ac_n "checking for correct version of mpfr.h""... $ac_c" 1>&6
-echo "configure:2372: checking for correct version of mpfr.h" >&5
+echo "configure:2374: checking for correct version of mpfr.h" >&5
cat > conftest.$ac_ext <
@@ -2382,7 +2384,7 @@
; return 0; }
EOF
-if { (eval echo configure:2386: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2388: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
echo "$ac_t""yes" 1>&6
else
@@ -2396,9 +2398,9 @@
saved_LIBS="$LIBS"
LIBS="$LIBS $gmplibs"
echo $ac_n "checking for any version of mpfr.h""... $ac_c" 1>&6
-echo "configure:2400: checking for any version of mpfr.h" >&5
+echo "configure:2402: checking for any version of mpfr.h" >&5
cat > conftest.$ac_ext <
#include
@@ -2406,7 +2408,7 @@
mpfr_t n; mpfr_init(n);
; return 0; }
EOF
-if { (eval echo configure:2410: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2412: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
echo "$ac_t""yes" 1>&6
else
@@ -3517,7 +3519,7 @@
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3521: checking for $ac_word" >&5
+echo "configure:3523: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3557,7 +3559,7 @@
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3561: checking for $ac_word" >&5
+echo "configure:3563: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_BISON'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3596,7 +3598,7 @@
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3600: checking for $ac_word" >&5
+echo "configure:3602: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_M4'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3635,7 +3637,7 @@
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3639: checking for $ac_word" >&5
+echo "configure:3641: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3675,7 +3677,7 @@
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3679: checking for $ac_word" >&5
+echo "configure:3681: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_FLEX'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3714,7 +3716,7 @@
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3718: checking for $ac_word" >&5
+echo "configure:3720: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_MAKEINFO'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3767,7 +3769,7 @@
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3771: checking for $ac_word" >&5
+echo "configure:3773: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_EXPECT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3808,7 +3810,7 @@
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3812: checking for $ac_word" >&5
+echo "configure:3814: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RUNTEST'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3856,7 +3858,7 @@
# Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3860: checking for $ac_word" >&5
+echo "configure:3862: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3887,7 +3889,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3891: checking for $ac_word" >&5
+echo "configure:3893: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3931,7 +3933,7 @@
# Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3935: checking for $ac_word" >&5
+echo "configure:3937: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3962,7 +3964,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3966: checking for $ac_word" >&5
+echo "configure:3968: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4006,7 +4008,7 @@
# Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4010: checking for $ac_word" >&5
+echo "configure:4012: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4037,7 +4039,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4041: checking for $ac_word" >&5
+echo "configure:4043: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4081,7 +4083,7 @@
# Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4085: checking for $ac_word" >&5
+echo "configure:4087: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4112,7 +4114,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4116: checking for $ac_word" >&5
+echo "configure:4118: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4156,7 +4158,7 @@
# Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4160: checking for $ac_word" >&5
+echo "configure:4162: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LIPO'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4187,7 +4189,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4191: checking for $ac_word" >&5
+echo "configure:4193: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LIPO'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4231,7 +4233,7 @@
# Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4235: checking for $ac_word" >&5
+echo "configure:4237: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_NM'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4262,7 +4264,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4266: checking for $ac_word" >&5
+echo "configure:4268: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_NM'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4306,7 +4308,7 @@
# Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4310: checking for $ac_word" >&5
+echo "configure:4312: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4337,7 +4339,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4341: checking for $ac_word" >&5
+echo "configure:4343: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4376,7 +4378,7 @@
# Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4380: checking for $ac_word" >&5
+echo "configure:4382: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4407,7 +4409,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4411: checking for $ac_word" >&5
+echo "configure:4413: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4446,7 +4448,7 @@
# Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4450: checking for $ac_word" >&5
+echo "configure:4452: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_WINDRES'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4477,7 +4479,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4481: checking for $ac_word" >&5
+echo "configure:4483: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_WINDRES'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4521,7 +4523,7 @@
# Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4525: checking for $ac_word" >&5
+echo "configure:4527: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_OBJCOPY'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4552,7 +4554,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4556: checking for $ac_word" >&5
+echo "configure:4558: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_OBJCOPY'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4596,7 +4598,7 @@
# Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4600: checking for $ac_word" >&5
+echo "configure:4602: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4627,7 +4629,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4631: checking for $ac_word" >&5
+echo "configure:4633: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4691,7 +4693,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in cc gcc; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:4695: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:4697: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_CC_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -4708,7 +4710,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4712: checking for $ac_word" >&5
+echo "configure:4714: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4739,7 +4741,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4743: checking for $ac_word" >&5
+echo "configure:4745: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4784,7 +4786,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in c++ g++ cxx gxx; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:4788: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:4790: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_CXX_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -4801,7 +4803,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4805: checking for $ac_word" >&5
+echo "configure:4807: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CXX_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4832,7 +4834,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4836: checking for $ac_word" >&5
+echo "configure:4838: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CXX_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4877,7 +4879,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in gcc; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:4881: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:4883: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_GCC_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -4894,7 +4896,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4898: checking for $ac_word" >&5
+echo "configure:4900: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_GCC_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4925,7 +4927,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4929: checking for $ac_word" >&5
+echo "configure:4931: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_GCC_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4965,7 +4967,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in gcj; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:4969: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:4971: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_GCJ_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -4982,7 +4984,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4986: checking for $ac_word" >&5
+echo "configure:4988: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_GCJ_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5013,7 +5015,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5017: checking for $ac_word" >&5
+echo "configure:5019: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_GCJ_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5058,7 +5060,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in gfortran; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:5062: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:5064: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_GFORTRAN_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -5075,7 +5077,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5079: checking for $ac_word" >&5
+echo "configure:5081: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_GFORTRAN_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5106,7 +5108,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5110: checking for $ac_word" >&5
+echo "configure:5112: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_GFORTRAN_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5215,7 +5217,7 @@
if test -z "$ac_cv_path_AR_FOR_TARGET" ; then
if test -n "$with_build_time_tools"; then
echo $ac_n "checking for ar in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:5219: checking for ar in $with_build_time_tools" >&5
+echo "configure:5221: checking for ar in $with_build_time_tools" >&5
if test -x $with_build_time_tools/ar; then
AR_FOR_TARGET=`cd $with_build_time_tools && pwd`/ar
ac_cv_path_AR_FOR_TARGET=$AR_FOR_TARGET
@@ -5233,7 +5235,7 @@
# Extract the first word of "ar", so it can be a program name with args.
set dummy ar; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5237: checking for $ac_word" >&5
+echo "configure:5239: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_AR_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5270,7 +5272,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in ar; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:5274: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:5276: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_AR_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -5287,7 +5289,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5291: checking for $ac_word" >&5
+echo "configure:5293: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AR_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5318,7 +5320,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5322: checking for $ac_word" >&5
+echo "configure:5324: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AR_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5370,7 +5372,7 @@
if test -z "$ac_cv_path_AS_FOR_TARGET" ; then
if test -n "$with_build_time_tools"; then
echo $ac_n "checking for as in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:5374: checking for as in $with_build_time_tools" >&5
+echo "configure:5376: checking for as in $with_build_time_tools" >&5
if test -x $with_build_time_tools/as; then
AS_FOR_TARGET=`cd $with_build_time_tools && pwd`/as
ac_cv_path_AS_FOR_TARGET=$AS_FOR_TARGET
@@ -5388,7 +5390,7 @@
# Extract the first word of "as", so it can be a program name with args.
set dummy as; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5392: checking for $ac_word" >&5
+echo "configure:5394: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_AS_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5425,7 +5427,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in as; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:5429: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:5431: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_AS_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -5442,7 +5444,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5446: checking for $ac_word" >&5
+echo "configure:5448: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AS_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5473,7 +5475,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5477: checking for $ac_word" >&5
+echo "configure:5479: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AS_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5525,7 +5527,7 @@
if test -z "$ac_cv_path_DLLTOOL_FOR_TARGET" ; then
if test -n "$with_build_time_tools"; then
echo $ac_n "checking for dlltool in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:5529: checking for dlltool in $with_build_time_tools" >&5
+echo "configure:5531: checking for dlltool in $with_build_time_tools" >&5
if test -x $with_build_time_tools/dlltool; then
DLLTOOL_FOR_TARGET=`cd $with_build_time_tools && pwd`/dlltool
ac_cv_path_DLLTOOL_FOR_TARGET=$DLLTOOL_FOR_TARGET
@@ -5543,7 +5545,7 @@
# Extract the first word of "dlltool", so it can be a program name with args.
set dummy dlltool; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5547: checking for $ac_word" >&5
+echo "configure:5549: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_DLLTOOL_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5580,7 +5582,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in dlltool; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:5584: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:5586: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_DLLTOOL_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -5597,7 +5599,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5601: checking for $ac_word" >&5
+echo "configure:5603: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5628,7 +5630,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5632: checking for $ac_word" >&5
+echo "configure:5634: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5680,7 +5682,7 @@
if test -z "$ac_cv_path_LD_FOR_TARGET" ; then
if test -n "$with_build_time_tools"; then
echo $ac_n "checking for ld in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:5684: checking for ld in $with_build_time_tools" >&5
+echo "configure:5686: checking for ld in $with_build_time_tools" >&5
if test -x $with_build_time_tools/ld; then
LD_FOR_TARGET=`cd $with_build_time_tools && pwd`/ld
ac_cv_path_LD_FOR_TARGET=$LD_FOR_TARGET
@@ -5698,7 +5700,7 @@
# Extract the first word of "ld", so it can be a program name with args.
set dummy ld; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5702: checking for $ac_word" >&5
+echo "configure:5704: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_LD_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5735,7 +5737,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in ld; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:5739: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:5741: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_LD_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -5752,7 +5754,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5756: checking for $ac_word" >&5
+echo "configure:5758: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LD_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5783,7 +5785,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5787: checking for $ac_word" >&5
+echo "configure:5789: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LD_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5835,7 +5837,7 @@
if test -z "$ac_cv_path_LIPO_FOR_TARGET" ; then
if test -n "$with_build_time_tools"; then
echo $ac_n "checking for lipo in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:5839: checking for lipo in $with_build_time_tools" >&5
+echo "configure:5841: checking for lipo in $with_build_time_tools" >&5
if test -x $with_build_time_tools/lipo; then
LIPO_FOR_TARGET=`cd $with_build_time_tools && pwd`/lipo
ac_cv_path_LIPO_FOR_TARGET=$LIPO_FOR_TARGET
@@ -5853,7 +5855,7 @@
# Extract the first word of "lipo", so it can be a program name with args.
set dummy lipo; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5857: checking for $ac_word" >&5
+echo "configure:5859: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_LIPO_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5890,7 +5892,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in lipo; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:5894: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:5896: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_LIPO_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -5907,7 +5909,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5911: checking for $ac_word" >&5
+echo "configure:5913: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LIPO_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5938,7 +5940,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5942: checking for $ac_word" >&5
+echo "configure:5944: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LIPO_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -5990,7 +5992,7 @@
if test -z "$ac_cv_path_NM_FOR_TARGET" ; then
if test -n "$with_build_time_tools"; then
echo $ac_n "checking for nm in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:5994: checking for nm in $with_build_time_tools" >&5
+echo "configure:5996: checking for nm in $with_build_time_tools" >&5
if test -x $with_build_time_tools/nm; then
NM_FOR_TARGET=`cd $with_build_time_tools && pwd`/nm
ac_cv_path_NM_FOR_TARGET=$NM_FOR_TARGET
@@ -6008,7 +6010,7 @@
# Extract the first word of "nm", so it can be a program name with args.
set dummy nm; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6012: checking for $ac_word" >&5
+echo "configure:6014: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_NM_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6045,7 +6047,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in nm; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:6049: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:6051: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_NM_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -6062,7 +6064,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6066: checking for $ac_word" >&5
+echo "configure:6068: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_NM_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6093,7 +6095,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6097: checking for $ac_word" >&5
+echo "configure:6099: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_NM_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6145,7 +6147,7 @@
if test -z "$ac_cv_path_OBJDUMP_FOR_TARGET" ; then
if test -n "$with_build_time_tools"; then
echo $ac_n "checking for objdump in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:6149: checking for objdump in $with_build_time_tools" >&5
+echo "configure:6151: checking for objdump in $with_build_time_tools" >&5
if test -x $with_build_time_tools/objdump; then
OBJDUMP_FOR_TARGET=`cd $with_build_time_tools && pwd`/objdump
ac_cv_path_OBJDUMP_FOR_TARGET=$OBJDUMP_FOR_TARGET
@@ -6163,7 +6165,7 @@
# Extract the first word of "objdump", so it can be a program name with args.
set dummy objdump; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6167: checking for $ac_word" >&5
+echo "configure:6169: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_OBJDUMP_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6200,7 +6202,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in objdump; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:6204: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:6206: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_OBJDUMP_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -6217,7 +6219,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6221: checking for $ac_word" >&5
+echo "configure:6223: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6248,7 +6250,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6252: checking for $ac_word" >&5
+echo "configure:6254: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6300,7 +6302,7 @@
if test -z "$ac_cv_path_RANLIB_FOR_TARGET" ; then
if test -n "$with_build_time_tools"; then
echo $ac_n "checking for ranlib in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:6304: checking for ranlib in $with_build_time_tools" >&5
+echo "configure:6306: checking for ranlib in $with_build_time_tools" >&5
if test -x $with_build_time_tools/ranlib; then
RANLIB_FOR_TARGET=`cd $with_build_time_tools && pwd`/ranlib
ac_cv_path_RANLIB_FOR_TARGET=$RANLIB_FOR_TARGET
@@ -6318,7 +6320,7 @@
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6322: checking for $ac_word" >&5
+echo "configure:6324: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_RANLIB_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6355,7 +6357,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in ranlib; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:6359: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:6361: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_RANLIB_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -6372,7 +6374,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6376: checking for $ac_word" >&5
+echo "configure:6378: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6403,7 +6405,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6407: checking for $ac_word" >&5
+echo "configure:6409: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6455,7 +6457,7 @@
if test -z "$ac_cv_path_STRIP_FOR_TARGET" ; then
if test -n "$with_build_time_tools"; then
echo $ac_n "checking for strip in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:6459: checking for strip in $with_build_time_tools" >&5
+echo "configure:6461: checking for strip in $with_build_time_tools" >&5
if test -x $with_build_time_tools/strip; then
STRIP_FOR_TARGET=`cd $with_build_time_tools && pwd`/strip
ac_cv_path_STRIP_FOR_TARGET=$STRIP_FOR_TARGET
@@ -6473,7 +6475,7 @@
# Extract the first word of "strip", so it can be a program name with args.
set dummy strip; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6477: checking for $ac_word" >&5
+echo "configure:6479: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_STRIP_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6510,7 +6512,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in strip; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:6514: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:6516: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_STRIP_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -6527,7 +6529,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6531: checking for $ac_word" >&5
+echo "configure:6533: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_STRIP_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6558,7 +6560,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6562: checking for $ac_word" >&5
+echo "configure:6564: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_STRIP_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6610,7 +6612,7 @@
if test -z "$ac_cv_path_WINDRES_FOR_TARGET" ; then
if test -n "$with_build_time_tools"; then
echo $ac_n "checking for windres in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:6614: checking for windres in $with_build_time_tools" >&5
+echo "configure:6616: checking for windres in $with_build_time_tools" >&5
if test -x $with_build_time_tools/windres; then
WINDRES_FOR_TARGET=`cd $with_build_time_tools && pwd`/windres
ac_cv_path_WINDRES_FOR_TARGET=$WINDRES_FOR_TARGET
@@ -6628,7 +6630,7 @@
# Extract the first word of "windres", so it can be a program name with args.
set dummy windres; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6632: checking for $ac_word" >&5
+echo "configure:6634: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_WINDRES_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6665,7 +6667,7 @@
if test -n "$with_build_time_tools"; then
for ncn_progname in windres; do
echo $ac_n "checking for ${ncn_progname} in $with_build_time_tools""... $ac_c" 1>&6
-echo "configure:6669: checking for ${ncn_progname} in $with_build_time_tools" >&5
+echo "configure:6671: checking for ${ncn_progname} in $with_build_time_tools" >&5
if test -x $with_build_time_tools/${ncn_progname}; then
ac_cv_prog_WINDRES_FOR_TARGET=$with_build_time_tools/${ncn_progname}
echo "$ac_t""yes" 1>&6
@@ -6682,7 +6684,7 @@
# Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6686: checking for $ac_word" >&5
+echo "configure:6688: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_WINDRES_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6713,7 +6715,7 @@
# Extract the first word of "${ncn_progname}", so it can be a program name with args.
set dummy ${ncn_progname}; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6717: checking for $ac_word" >&5
+echo "configure:6719: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_WINDRES_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6763,7 +6765,7 @@
RAW_CXX_FOR_TARGET="$CXX_FOR_TARGET"
echo $ac_n "checking where to find the target ar""... $ac_c" 1>&6
-echo "configure:6767: checking where to find the target ar" >&5
+echo "configure:6769: checking where to find the target ar" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$AR_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -6796,7 +6798,7 @@
fi
fi
echo $ac_n "checking where to find the target as""... $ac_c" 1>&6
-echo "configure:6800: checking where to find the target as" >&5
+echo "configure:6802: checking where to find the target as" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$AS_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -6829,7 +6831,7 @@
fi
fi
echo $ac_n "checking where to find the target cc""... $ac_c" 1>&6
-echo "configure:6833: checking where to find the target cc" >&5
+echo "configure:6835: checking where to find the target cc" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$CC_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -6862,7 +6864,7 @@
fi
fi
echo $ac_n "checking where to find the target c++""... $ac_c" 1>&6
-echo "configure:6866: checking where to find the target c++" >&5
+echo "configure:6868: checking where to find the target c++" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$CXX_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -6898,7 +6900,7 @@
fi
fi
echo $ac_n "checking where to find the target c++ for libstdc++""... $ac_c" 1>&6
-echo "configure:6902: checking where to find the target c++ for libstdc++" >&5
+echo "configure:6904: checking where to find the target c++ for libstdc++" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$RAW_CXX_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -6934,7 +6936,7 @@
fi
fi
echo $ac_n "checking where to find the target dlltool""... $ac_c" 1>&6
-echo "configure:6938: checking where to find the target dlltool" >&5
+echo "configure:6940: checking where to find the target dlltool" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$DLLTOOL_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -6967,7 +6969,7 @@
fi
fi
echo $ac_n "checking where to find the target gcc""... $ac_c" 1>&6
-echo "configure:6971: checking where to find the target gcc" >&5
+echo "configure:6973: checking where to find the target gcc" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$GCC_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -7000,7 +7002,7 @@
fi
fi
echo $ac_n "checking where to find the target gcj""... $ac_c" 1>&6
-echo "configure:7004: checking where to find the target gcj" >&5
+echo "configure:7006: checking where to find the target gcj" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$GCJ_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -7036,7 +7038,7 @@
fi
fi
echo $ac_n "checking where to find the target gfortran""... $ac_c" 1>&6
-echo "configure:7040: checking where to find the target gfortran" >&5
+echo "configure:7042: checking where to find the target gfortran" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$GFORTRAN_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -7072,7 +7074,7 @@
fi
fi
echo $ac_n "checking where to find the target ld""... $ac_c" 1>&6
-echo "configure:7076: checking where to find the target ld" >&5
+echo "configure:7078: checking where to find the target ld" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$LD_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -7105,7 +7107,7 @@
fi
fi
echo $ac_n "checking where to find the target lipo""... $ac_c" 1>&6
-echo "configure:7109: checking where to find the target lipo" >&5
+echo "configure:7111: checking where to find the target lipo" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$LIPO_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -7128,7 +7130,7 @@
fi
fi
echo $ac_n "checking where to find the target nm""... $ac_c" 1>&6
-echo "configure:7132: checking where to find the target nm" >&5
+echo "configure:7134: checking where to find the target nm" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$NM_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -7161,7 +7163,7 @@
fi
fi
echo $ac_n "checking where to find the target objdump""... $ac_c" 1>&6
-echo "configure:7165: checking where to find the target objdump" >&5
+echo "configure:7167: checking where to find the target objdump" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$OBJDUMP_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -7194,7 +7196,7 @@
fi
fi
echo $ac_n "checking where to find the target ranlib""... $ac_c" 1>&6
-echo "configure:7198: checking where to find the target ranlib" >&5
+echo "configure:7200: checking where to find the target ranlib" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$RANLIB_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -7227,7 +7229,7 @@
fi
fi
echo $ac_n "checking where to find the target strip""... $ac_c" 1>&6
-echo "configure:7231: checking where to find the target strip" >&5
+echo "configure:7233: checking where to find the target strip" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$STRIP_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -7260,7 +7262,7 @@
fi
fi
echo $ac_n "checking where to find the target windres""... $ac_c" 1>&6
-echo "configure:7264: checking where to find the target windres" >&5
+echo "configure:7266: checking where to find the target windres" >&5
if test "x${build}" != "x${host}" ; then
if expr "x$WINDRES_FOR_TARGET" : "x/" > /dev/null; then
# We already found the complete path
@@ -7321,7 +7323,7 @@
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:7325: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:7327: checking whether to enable maintainer-specific portions of Makefiles" >&5
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
if test "${enable_maintainer_mode+set}" = set; then
enableval="$enable_maintainer_mode"
@@ -7370,9 +7372,9 @@
# Pass -fkeep-inline-functions for stage 1 if the GCC version supports it.
CFLAGS="$CFLAGS -fkeep-inline-functions"
echo $ac_n "checking whether -fkeep-inline-functions is supported""... $ac_c" 1>&6
-echo "configure:7374: checking whether -fkeep-inline-functions is supported" >&5
+echo "configure:7376: checking whether -fkeep-inline-functions is supported" >&5
cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7391: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
echo "$ac_t""yes" 1>&6; stage1_cflags="$stage1_cflags -fkeep-inline-functions"
else
Modified: llvm-gcc-4.2/trunk/configure.in
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/configure.in?rev=42989&r1=42988&r2=42989&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/configure.in (original)
+++ llvm-gcc-4.2/trunk/configure.in Mon Oct 15 11:01:08 2007
@@ -376,6 +376,8 @@
noconfigdirs="$noconfigdirs ld gas gdb gprof"
noconfigdirs="$noconfigdirs sim target-rda"
noconfigdirs="$noconfigdirs ${libgcj} target-libstdc++-v3"
+ # LLVM LOCAL
+ noconfigdirs="$noconfigdirs target-libobjc"
;;
*-*-freebsd[[12]] | *-*-freebsd[[12]].* | *-*-freebsd*aout*)
noconfigdirs="$noconfigdirs target-newlib target-libgloss ${libgcj}"
From tonic at nondot.org Mon Oct 15 11:35:13 2007
From: tonic at nondot.org (Tanya Lattner)
Date: Mon, 15 Oct 2007 16:35:13 -0000
Subject: [llvm-commits] [llvm] r42990 -
/llvm/trunk/test/CodeGen/X86/2007-10-14-CoalescerCrash.ll
Message-ID: <200710151635.l9FGZDad000701@zion.cs.uiuc.edu>
Author: tbrethou
Date: Mon Oct 15 11:35:13 2007
New Revision: 42990
URL: http://llvm.org/viewvc/llvm-project?rev=42990&view=rev
Log:
Fix run line.
Modified:
llvm/trunk/test/CodeGen/X86/2007-10-14-CoalescerCrash.ll
Modified: llvm/trunk/test/CodeGen/X86/2007-10-14-CoalescerCrash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-10-14-CoalescerCrash.ll?rev=42990&r1=42989&r2=42990&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2007-10-14-CoalescerCrash.ll (original)
+++ llvm/trunk/test/CodeGen/X86/2007-10-14-CoalescerCrash.ll Mon Oct 15 11:35:13 2007
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | \
+; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin
%struct._Unwind_Context = type { }
From lattner at apple.com Mon Oct 15 11:35:38 2007
From: lattner at apple.com (Tanya Lattner)
Date: Mon, 15 Oct 2007 09:35:38 -0700
Subject: [llvm-commits] [llvm] r42963 -
/llvm/trunk/test/CodeGen/X86/2007-10-14-CoalescerCrash.ll
In-Reply-To: <9986BF9A-FAF3-4C0A-AA0B-0AC636C77B9D@gmail.com>
References: <200710141015.l9EAF3hi017832@zion.cs.uiuc.edu>
<9986BF9A-FAF3-4C0A-AA0B-0AC636C77B9D@gmail.com>
Message-ID: <5DC91550-8E9F-4AFE-92CA-17C9B1165263@apple.com>
I deleted the extra |\ at the end so the test would pass.
Evan, if thats not what you want, please fix.
Thanks,
Tanya
On Oct 14, 2007, at 3:47 AM, Bill Wendling wrote:
> On Oct 14, 2007, at 3:15 AM, Evan Cheng wrote:
>
>> +; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | \
>> +
> The backslash-newline looks suspect.
>
> -bw
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
From clattner at apple.com Mon Oct 15 11:46:19 2007
From: clattner at apple.com (Chris Lattner)
Date: Mon, 15 Oct 2007 09:46:19 -0700
Subject: [llvm-commits] [llvm] r42981 - in /llvm/trunk:
include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp utils/TableGen/DAGISelEmitter.cpp
In-Reply-To: <200710151401.46887.baldrick@free.fr>
References: <200710150610.l9F6ANV3030436@zion.cs.uiuc.edu>
<200710151401.46887.baldrick@free.fr>
Message-ID:
On Oct 15, 2007, at 5:01 AM, Duncan Sands wrote:
> Hi Chris, this sounds like a big improvement! Where did you find
> the time
> to do this?!
:) "You don't find time, you make time." This is something we've
needed for a long time, and your recent work on supporting apint's
made it even more necessary.
>> 2. SoftFP is a mess, I need to talk to Evan about it.
>
> Presumably f64 will be promoted to i64 then possibly expanded into
> 2xi32,
> rather than mulching the two steps together in expand as is done now.
Yes, exactly.
> Codegen
> support for arbitrary precision integers also needs to promote to a
> type which
> is then expanded. Does your new infrastructure support this
> (currently expand
> is only allowed to follow expand, not promote)?
Untested, but yes it should :)
> Dunno if it's useful to support
> promote following promote/expand - I don't have a use for it, and
> forbidding
> it would help prevent infinite promote/expand loops.
I don't have any explicit support for one or the other. It just
supports relegalizing nodes after they've been transformed.
>> 5. The code nicely separates out handling of operations with invalid
>> results from operations with invalid operands, making some cases
>> simpler and easier to understand.
>
> Yay!
>
> The following two comments seem contradictory. The first one suggests
> that operations are not legalized...
It separates handling "results vs operands" of a node.
>> ... This legalizer is designed to run before the
>> operation legalizer and ensure just that the input dag is transformed
>> into an output dag whose operand and result types are all legal, even
>> if the operations on those types are not.
>
> While here it sounds like operations are legalized...
Nope, not intentionally. :) The type legalizer does not legalize
operations, only types :)
>
>> + enum LegalizeAction {
>> + Legal, // The target natively supports this operation.
>
> -> The target natively supports this type.
>
>> + Promote, // This operation should be executed in a larger
>> type.
>
> -> This type should be replaced with a larger type.
>
>> + Expand // Try to expand this to other ops, otherwise use
>> a libcall.
>
> -> This type should be split into two types of half the size.
Fixed, pasto :)
>
>
>> + /// ValueTypeActions - This is a bitvector that contains two
>> bits for each
>> + /// value type, where the two bits correspond to the
>> LegalizeAction enum.
>
> value type -> simple value type
> That said, I will work on adding support for extended value types
> myself, so I
> won't mention extended value types in the result of this email.
Ok, thx for fixing.
> By the way the logic supposes that the result of any node is an
> operand for
> some other node. Is at least one result always used?
Nope, nodes are allowed to be unreachable/dead. What part assumes
that they are used?
>> + // If the node needs revisitation, don't add all users to the
>> worklist etc.
>
> revisitation -> revisiting
> Or is this a technical term? It's used several times.
Just me accidentally making up new words, fixed.
Thanks Duncan!
-Chris
From sabre at nondot.org Mon Oct 15 11:46:29 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 15 Oct 2007 16:46:29 -0000
Subject: [llvm-commits] [llvm] r42991 -
/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
Message-ID: <200710151646.l9FGkTMA001465@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Oct 15 11:46:29 2007
New Revision: 42991
URL: http://llvm.org/viewvc/llvm-project?rev=42991&view=rev
Log:
updates from duncan
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=42991&r1=42990&r2=42991&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Mon Oct 15 11:46:29 2007
@@ -55,9 +55,9 @@
};
enum LegalizeAction {
- Legal, // The target natively supports this operation.
- Promote, // This operation should be executed in a larger type.
- Expand // Try to expand this to other ops, otherwise use a libcall.
+ Legal, // The target natively supports this type.
+ Promote, // This type should be executed in a larger type.
+ Expand // This type should be split into two types of half the size.
};
/// ValueTypeActions - This is a bitvector that contains two bits for each
@@ -244,7 +244,7 @@
}
}
- // If the node needs revisitation, don't add all users to the worklist etc.
+ // If the node needs revisiting, don't add all users to the worklist etc.
if (NeedsRevisit)
continue;
@@ -328,7 +328,7 @@
// Okay, we know that this node is new. Recursively walk all of its operands
// to see if they are new also. The depth of this walk is bounded by the size
// of the new tree that was constructed (usually 2-3 nodes), so we don't worry
- // about revisitation of nodes.
+ // about revisitating of nodes.
//
// As we walk the operands, keep track of the number of nodes that are
// processed. If non-zero, this will become the new nodeid of this node.
From sabre at nondot.org Mon Oct 15 12:16:12 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 15 Oct 2007 17:16:12 -0000
Subject: [llvm-commits] [llvm] r42992 -
/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
Message-ID: <200710151716.l9FHGCUr002887@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Oct 15 12:16:12 2007
New Revision: 42992
URL: http://llvm.org/viewvc/llvm-project?rev=42992&view=rev
Log:
implement promotion of BR_CC operands, fixing bisort on ppc.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=42992&r1=42991&r2=42992&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Mon Oct 15 12:16:12 2007
@@ -161,8 +161,11 @@
SDOperand PromoteOperand_FP_ROUND(SDNode *N);
SDOperand PromoteOperand_SELECT(SDNode *N, unsigned OpNo);
SDOperand PromoteOperand_BRCOND(SDNode *N, unsigned OpNo);
+ SDOperand PromoteOperand_BR_CC(SDNode *N, unsigned OpNo);
SDOperand PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo);
+ void PromoteSetCCOperands(SDOperand &LHS,SDOperand &RHS, ISD::CondCode Code);
+
// Operand Expansion.
bool ExpandOperand(SDNode *N, unsigned OperandNo);
SDOperand ExpandOperand_TRUNCATE(SDNode *N);
@@ -328,7 +331,7 @@
// Okay, we know that this node is new. Recursively walk all of its operands
// to see if they are new also. The depth of this walk is bounded by the size
// of the new tree that was constructed (usually 2-3 nodes), so we don't worry
- // about revisitating of nodes.
+ // about revisiting of nodes.
//
// As we walk the operands, keep track of the number of nodes that are
// processed. If non-zero, this will become the new nodeid of this node.
@@ -1141,6 +1144,8 @@
case ISD::SELECT: Res = PromoteOperand_SELECT(N, OpNo); break;
case ISD::BRCOND: Res = PromoteOperand_BRCOND(N, OpNo); break;
+ case ISD::BR_CC: Res = PromoteOperand_BR_CC(N, OpNo); break;
+
case ISD::STORE: Res = PromoteOperand_STORE(cast(N),
OpNo); break;
}
@@ -1226,6 +1231,64 @@
N->getOperand(2));
}
+SDOperand DAGTypeLegalizer::PromoteOperand_BR_CC(SDNode *N, unsigned OpNo) {
+ assert(OpNo == 2 && "Don't know how to promote this operand");
+
+ SDOperand LHS = N->getOperand(2);
+ SDOperand RHS = N->getOperand(3);
+ PromoteSetCCOperands(LHS, RHS, cast(N->getOperand(1))->get());
+
+ // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always
+ // legal types.
+ return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
+ N->getOperand(1), LHS, RHS, N->getOperand(4));
+}
+
+/// PromoteSetCCOperands - Promote the operands of a comparison. This code is
+/// shared among BR_CC, SELECT_CC, and SETCC handlers.
+void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
+ ISD::CondCode CCCode) {
+ MVT::ValueType VT = NewLHS.getValueType();
+
+ // Get the promoted values.
+ NewLHS = GetPromotedOp(NewLHS);
+ NewRHS = GetPromotedOp(NewRHS);
+
+ // If this is an FP compare, the operands have already been extended.
+ if (!MVT::isInteger(NewLHS.getValueType()))
+ return;
+
+ // Otherwise, we have to insert explicit sign or zero extends. Note
+ // that we could insert sign extends for ALL conditions, but zero extend
+ // is cheaper on many machines (an AND instead of two shifts), so prefer
+ // it.
+ switch (CCCode) {
+ default: assert(0 && "Unknown integer comparison!");
+ case ISD::SETEQ:
+ case ISD::SETNE:
+ case ISD::SETUGE:
+ case ISD::SETUGT:
+ case ISD::SETULE:
+ case ISD::SETULT:
+ // ALL of these operations will work if we either sign or zero extend
+ // the operands (including the unsigned comparisons!). Zero extend is
+ // usually a simpler/cheaper operation, so prefer it.
+ NewLHS = DAG.getZeroExtendInReg(NewLHS, VT);
+ NewRHS = DAG.getZeroExtendInReg(NewRHS, VT);
+ return;
+ case ISD::SETGE:
+ case ISD::SETGT:
+ case ISD::SETLT:
+ case ISD::SETLE:
+ NewLHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewLHS.getValueType(), NewLHS,
+ DAG.getValueType(VT));
+ NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS,
+ DAG.getValueType(VT));
+ return;
+ }
+}
+
+
SDOperand DAGTypeLegalizer::PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo){
SDOperand Ch = N->getChain(), Ptr = N->getBasePtr();
int SVOffset = N->getSrcValueOffset();
@@ -1316,7 +1379,7 @@
DAG.getCondCode(CCCode));
}
-/// ExpandSetCCOperands - Expand the operands to a comparison. This code is
+/// ExpandSetCCOperands - Expand the operands of a comparison. This code is
/// shared among BR_CC, SELECT_CC, and SETCC handlers.
void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
ISD::CondCode &CCCode) {
From dpatel at apple.com Mon Oct 15 12:29:17 2007
From: dpatel at apple.com (Devang Patel)
Date: Mon, 15 Oct 2007 17:29:17 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r42993 - in /llvm-gcc-4.2/trunk/gcc:
llvm-convert.cpp llvm-types.cpp
Message-ID: <200710151729.l9FHTHRM003477@zion.cs.uiuc.edu>
Author: dpatel
Date: Mon Oct 15 12:29:14 2007
New Revision: 42993
URL: http://llvm.org/viewvc/llvm-project?rev=42993&view=rev
Log:
Fix
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20071015/054529.html
Modified:
llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=42993&r1=42992&r2=42993&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Oct 15 12:29:14 2007
@@ -4838,13 +4838,20 @@
// float foo(int w, float A[][w], int g) { return A[g][0]; }
ArrayAddr = BitCastToType(ArrayAddr, PointerType::get(Type::Int8Ty));
- Value *TypeSize = Emit(array_ref_element_size(exp), 0);
- TypeSize = CastToUIntType(TypeSize, IntPtrTy);
+ Value *TypeSize = NULL;
+ if (VOID_TYPE_P(TREE_TYPE(ArrayType))) {
+ Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
+ return BitCastToType(Ptr, PointerType::get(Type::Int8Ty));
+ }
+ else {
+ TypeSize = Emit(array_ref_element_size(exp), 0);
+ TypeSize = CastToUIntType(TypeSize, IntPtrTy);
+ IndexVal = Builder.CreateMul(IndexVal, TypeSize, "tmp");
+ Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
+ return BitCastToType(Ptr, PointerType::get(ConvertType(TREE_TYPE(exp))));
+ }
- IndexVal = Builder.CreateMul(IndexVal, TypeSize, "tmp");
- Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
- return BitCastToType(Ptr, PointerType::get(ConvertType(TREE_TYPE(exp))));
}
/// getFieldOffsetInBits - Return the offset (in bits) of a FIELD_DECL in a
Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=42993&r1=42992&r2=42993&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Mon Oct 15 12:29:14 2007
@@ -303,7 +303,7 @@
TREE_CODE(type) == REFERENCE_TYPE) && "not a sequential type!");
// This relies on gcc types with constant size mapping to LLVM types with the
// same size.
- return isInt64(TYPE_SIZE(TREE_TYPE(type)), true);
+ return !VOID_TYPE_P(TREE_TYPE(type)) && isInt64(TYPE_SIZE(TREE_TYPE(type)), true);
}
/// isArrayCompatible - Return true if the specified gcc array or pointer type
From dalej at apple.com Mon Oct 15 12:36:45 2007
From: dalej at apple.com (Dale Johannesen)
Date: Mon, 15 Oct 2007 10:36:45 -0700
Subject: [llvm-commits] [llvm] r42991 -
/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
In-Reply-To: <200710151646.l9FGkTMA001465@zion.cs.uiuc.edu>
References: <200710151646.l9FGkTMA001465@zion.cs.uiuc.edu>
Message-ID: <4CC6E082-2B40-4824-99C6-3727DBB593EA@apple.com>
On Oct 15, 2007, at 9:46 AM, Chris Lattner wrote:
> @@ -328,7 +328,7 @@
> // Okay, we know that this node is new. Recursively walk all of
> its operands
> // to see if they are new also. The depth of this walk is
> bounded by the size
> // of the new tree that was constructed (usually 2-3 nodes), so
> we don't worry
> - // about revisitation of nodes.
> + // about revisitating of nodes.
> //
> // As we walk the operands, keep track of the number of nodes
> that are
> // processed. If non-zero, this will become the new nodeid of
> this node.
Actually 'revisitation' is a perfectly good word; but 'revisitating'
is not.
From sabre at nondot.org Mon Oct 15 12:47:20 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 15 Oct 2007 17:47:20 -0000
Subject: [llvm-commits] [llvm] r42994 - in /llvm/trunk:
include/llvm/CodeGen/SelectionDAG.h
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Message-ID: <200710151747.l9FHlK5Q004052@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Oct 15 12:47:20 2007
New Revision: 42994
URL: http://llvm.org/viewvc/llvm-project?rev=42994&view=rev
Log:
add a new CreateStackTemporary helper method.
Modified:
llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=42994&r1=42993&r2=42994&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Mon Oct 15 12:47:20 2007
@@ -492,6 +492,10 @@
void dump() const;
+ /// CreateStackTemporary - Create a stack temporary, suitable for holding the
+ /// specified value type.
+ SDOperand CreateStackTemporary(MVT::ValueType VT);
+
/// FoldSetCC - Constant fold a setcc to true or false.
SDOperand FoldSetCC(MVT::ValueType VT, SDOperand N1,
SDOperand N2, ISD::CondCode Cond);
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=42994&r1=42993&r2=42994&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Oct 15 12:47:20 2007
@@ -19,6 +19,7 @@
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetData.h"
@@ -913,6 +914,18 @@
return SDOperand(N, 0);
}
+/// CreateStackTemporary - Create a stack temporary, suitable for holding the
+/// specified value type.
+SDOperand SelectionDAG::CreateStackTemporary(MVT::ValueType VT) {
+ MachineFrameInfo *FrameInfo = getMachineFunction().getFrameInfo();
+ unsigned ByteSize = MVT::getSizeInBits(VT)/8;
+ const Type *Ty = MVT::getTypeForValueType(VT);
+ unsigned StackAlign = (unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty);
+ int FrameIdx = FrameInfo->CreateStackObject(ByteSize, StackAlign);
+ return getFrameIndex(FrameIdx, TLI.getPointerTy());
+}
+
+
SDOperand SelectionDAG::FoldSetCC(MVT::ValueType VT, SDOperand N1,
SDOperand N2, ISD::CondCode Cond) {
// These setcc operations always fold.
From sabre at nondot.org Mon Oct 15 12:48:57 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 15 Oct 2007 17:48:57 -0000
Subject: [llvm-commits] [llvm] r42995 -
/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Message-ID: <200710151748.l9FHmvwD004103@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Oct 15 12:48:57 2007
New Revision: 42995
URL: http://llvm.org/viewvc/llvm-project?rev=42995&view=rev
Log:
Move CreateStackTemporary out to SelectionDAG
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=42995&r1=42994&r2=42995&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Oct 15 12:48:57 2007
@@ -193,8 +193,6 @@
void LegalizeSetCCOperands(SDOperand &LHS, SDOperand &RHS, SDOperand &CC);
- SDOperand CreateStackTemporary(MVT::ValueType VT);
-
SDOperand ExpandLibCall(const char *Name, SDNode *Node, bool isSigned,
SDOperand &Hi);
SDOperand ExpandIntToFP(bool isSigned, MVT::ValueType DestTy,
@@ -1245,7 +1243,7 @@
MVT::ValueType EltVT = Tmp2.getValueType();
MVT::ValueType IdxVT = Tmp3.getValueType();
MVT::ValueType PtrVT = TLI.getPointerTy();
- SDOperand StackPtr = CreateStackTemporary(VT);
+ SDOperand StackPtr = DAG.CreateStackTemporary(VT);
// Store the vector.
SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Tmp1, StackPtr, NULL, 0);
@@ -4129,7 +4127,7 @@
} else {
// Store the value to a temporary stack slot, then LOAD the scalar
// element back out.
- SDOperand StackPtr = CreateStackTemporary(Vec.getValueType());
+ SDOperand StackPtr = DAG.CreateStackTemporary(Vec.getValueType());
SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0);
// Add the offset to the index.
@@ -4391,7 +4389,7 @@
Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi,
CCCode, false, DagCombineInfo);
if (!Tmp2.Val)
- Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), LHSHi, RHSHi, CC);
+ Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), LHSHi, RHSHi,CC);
ConstantSDNode *Tmp1C = dyn_cast(Tmp1.Val);
ConstantSDNode *Tmp2C = dyn_cast(Tmp2.Val);
@@ -4430,7 +4428,7 @@
SDOperand SelectionDAGLegalize::ExpandBIT_CONVERT(MVT::ValueType DestVT,
SDOperand SrcOp) {
// Create the stack frame object.
- SDOperand FIPtr = CreateStackTemporary(DestVT);
+ SDOperand FIPtr = DAG.CreateStackTemporary(DestVT);
// Emit a store to the stack slot.
SDOperand Store = DAG.getStore(DAG.getEntryNode(), SrcOp, FIPtr, NULL, 0);
@@ -4441,7 +4439,7 @@
SDOperand SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) {
// Create a vector sized/aligned stack slot, store the value to element #0,
// then load the whole vector back out.
- SDOperand StackPtr = CreateStackTemporary(Node->getValueType(0));
+ SDOperand StackPtr = DAG.CreateStackTemporary(Node->getValueType(0));
SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Node->getOperand(0), StackPtr,
NULL, 0);
return DAG.getLoad(Node->getValueType(0), Ch, StackPtr, NULL, 0);
@@ -4574,7 +4572,7 @@
// the result as a vector.
MVT::ValueType VT = Node->getValueType(0);
// Create the stack frame object.
- SDOperand FIPtr = CreateStackTemporary(VT);
+ SDOperand FIPtr = DAG.CreateStackTemporary(VT);
// Emit a store of each element to the stack slot.
SmallVector Stores;
@@ -4605,17 +4603,6 @@
return DAG.getLoad(VT, StoreChain, FIPtr, NULL, 0);
}
-/// CreateStackTemporary - Create a stack temporary, suitable for holding the
-/// specified value type.
-SDOperand SelectionDAGLegalize::CreateStackTemporary(MVT::ValueType VT) {
- MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
- unsigned ByteSize = MVT::getSizeInBits(VT)/8;
- const Type *Ty = MVT::getTypeForValueType(VT);
- unsigned StackAlign = (unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty);
- int FrameIdx = FrameInfo->CreateStackObject(ByteSize, StackAlign);
- return DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());
-}
-
void SelectionDAGLegalize::ExpandShiftParts(unsigned NodeOp,
SDOperand Op, SDOperand Amt,
SDOperand &Lo, SDOperand &Hi) {
@@ -6318,7 +6305,7 @@
// The input is a scalar or single-element vector.
// Lower to a store/load so that it can be split.
// FIXME: this could be improved probably.
- SDOperand Ptr = CreateStackTemporary(InOp.getValueType());
+ SDOperand Ptr = DAG.CreateStackTemporary(InOp.getValueType());
SDOperand St = DAG.getStore(DAG.getEntryNode(),
InOp, Ptr, NULL, 0);
From baldrick at free.fr Mon Oct 15 13:03:33 2007
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 15 Oct 2007 20:03:33 +0200
Subject: [llvm-commits] [llvm-gcc-4.2] r42993 - in
/llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-types.cpp
In-Reply-To: <200710151729.l9FHTHRM003477@zion.cs.uiuc.edu>
References: <200710151729.l9FHTHRM003477@zion.cs.uiuc.edu>
Message-ID: <200710152003.33404.baldrick@free.fr>
Hi Devang,
> // float foo(int w, float A[][w], int g) { return A[g][0]; }
>
> ArrayAddr = BitCastToType(ArrayAddr, PointerType::get(Type::Int8Ty));
> - Value *TypeSize = Emit(array_ref_element_size(exp), 0);
> - TypeSize = CastToUIntType(TypeSize, IntPtrTy);
> + Value *TypeSize = NULL;
since TypeSize is only used in the second branch of the "if", it could be
declared there.
> + if (VOID_TYPE_P(TREE_TYPE(ArrayType))) {
> + Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
> + return BitCastToType(Ptr, PointerType::get(Type::Int8Ty));
If ArrayAddr is not an i8*, then the CreateGEP line is wrong, so
this bitcast should be useless.
Ciao,
Duncan.
From evan.cheng at apple.com Mon Oct 15 13:33:51 2007
From: evan.cheng at apple.com (Evan Cheng)
Date: Mon, 15 Oct 2007 18:33:51 -0000
Subject: [llvm-commits] [llvm] r42996 - in /llvm/trunk:
lib/CodeGen/SimpleRegisterCoalescing.cpp
test/CodeGen/X86/2007-10-15-CoalescerCrash.ll
Message-ID: <200710151833.l9FIXpgi006206@zion.cs.uiuc.edu>
Author: evancheng
Date: Mon Oct 15 13:33:50 2007
New Revision: 42996
URL: http://llvm.org/viewvc/llvm-project?rev=42996&view=rev
Log:
Fix PR1729: watch out for val# with no def.
Added:
llvm/trunk/test/CodeGen/X86/2007-10-15-CoalescerCrash.ll
Modified:
llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=42996&r1=42995&r2=42996&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Mon Oct 15 13:33:50 2007
@@ -422,14 +422,19 @@
// then create and update the actual physical register allocated to RHS.
if (RealDstReg) {
LiveInterval &RealDstInt = li_->getOrCreateInterval(RealDstReg);
- for (unsigned i = 0, e = ResSrcInt->getNumValNums(); i != e; ++i) {
- const VNInfo *SrcValNo = ResSrcInt->getValNumInfo(i);
- const VNInfo *DstValNo =
- ResDstInt->FindLiveRangeContaining(SrcValNo->def)->valno;
- VNInfo *ValNo = RealDstInt.getNextValue(DstValNo->def, DstValNo->reg,
- li_->getVNInfoAllocator());
- RealDstInt.addKills(ValNo, DstValNo->kills);
- RealDstInt.MergeValueInAsValue(*ResDstInt, DstValNo, ValNo);
+ SmallSet CopiedValNos;
+ for (LiveInterval::Ranges::const_iterator I = ResSrcInt->ranges.begin(),
+ E = ResSrcInt->ranges.end(); I != E; ++I) {
+ LiveInterval::const_iterator DstLR =
+ ResDstInt->FindLiveRangeContaining(I->start);
+ assert(DstLR != ResDstInt->end() && "Invalid joined interval!");
+ const VNInfo *DstValNo = DstLR->valno;
+ if (CopiedValNos.insert(DstValNo)) {
+ VNInfo *ValNo = RealDstInt.getNextValue(DstValNo->def, DstValNo->reg,
+ li_->getVNInfoAllocator());
+ RealDstInt.addKills(ValNo, DstValNo->kills);
+ RealDstInt.MergeValueInAsValue(*ResDstInt, DstValNo, ValNo);
+ }
}
repDstReg = RealDstReg;
}
Added: llvm/trunk/test/CodeGen/X86/2007-10-15-CoalescerCrash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-10-15-CoalescerCrash.ll?rev=42996&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2007-10-15-CoalescerCrash.ll (added)
+++ llvm/trunk/test/CodeGen/X86/2007-10-15-CoalescerCrash.ll Mon Oct 15 13:33:50 2007
@@ -0,0 +1,400 @@
+; RUN: llvm-as < %s | llc -mtriple=x86_64-linux-gnu
+; PR1729
+
+ %struct.CUMULATIVE_ARGS = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }
+ %struct.VEC_edge = type { i32, i32, [1 x %struct.edge_def*] }
+ %struct.VEC_tree = type { i32, i32, [1 x %struct.tree_node*] }
+ %struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+ %struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+ %struct._obstack_chunk = type { i8*, %struct._obstack_chunk*, [4 x i8] }
+ %struct.addr_diff_vec_flags = type <{ i8, i8, i8, i8 }>
+ %struct.alloc_pool_def = type { i8*, i64, i64, %struct.alloc_pool_list_def*, i64, i64, i64, %struct.alloc_pool_list_def*, i64, i64 }
+ %struct.alloc_pool_list_def = type { %struct.alloc_pool_list_def* }
+ %struct.basic_block_def = type { %struct.rtx_def*, %struct.rtx_def*, %struct.tree_node*, %struct.VEC_edge*, %struct.VEC_edge*, %struct.bitmap_head_def*, %struct.bitmap_head_def*, i8*, %struct.loop*, [2 x %struct.et_node*], %struct.basic_block_def*, %struct.basic_block_def*, %struct.reorder_block_def*, %struct.bb_ann_d*, i64, i32, i32, i32, i32 }
+ %struct.bb_ann_d = type opaque
+ %struct.bitmap_element_def = type { %struct.bitmap_element_def*, %struct.bitmap_element_def*, i32, [2 x i64] }
+ %struct.bitmap_head_def = type { %struct.bitmap_element_def*, %struct.bitmap_element_def*, i32, %struct.bitmap_obstack* }
+ %struct.bitmap_obstack = type { %struct.bitmap_element_def*, %struct.bitmap_head_def*, %struct.obstack }
+ %struct.cselib_val_struct = type opaque
+ %struct.dataflow_d = type opaque
+ %struct.die_struct = type opaque
+ %struct.edge_def = type { %struct.basic_block_def*, %struct.basic_block_def*, %struct.edge_def_insns, i8*, %struct.location_t*, i32, i32, i64, i32 }
+ %struct.edge_def_insns = type { %struct.rtx_def* }
+ %struct.edge_iterator = type { i32, %struct.VEC_edge** }
+ %struct.eh_status = type opaque
+ %struct.elt_list = type opaque
+ %struct.emit_status = type { i32, i32, %struct.rtx_def*, %struct.rtx_def*, %struct.sequence_stack*, i32, %struct.location_t, i32, i8*, %struct.rtx_def** }
+ %struct.et_node = type opaque
+ %struct.expr_status = type { i32, i32, i32, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def* }
+ %struct.function = type { %struct.eh_status*, %struct.expr_status*, %struct.emit_status*, %struct.varasm_status*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.function*, i32, i32, i32, i32, %struct.rtx_def*, %struct.CUMULATIVE_ARGS, %struct.rtx_def*, %struct.rtx_def*, %struct.initial_value_struct*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, i8, i32, i64, %struct.tree_node*, %struct.tree_node*, %struct.rtx_def*, %struct.varray_head_tag*, %struct.temp_slot*, i32, %struct.var_refs_queue*, i32, i32, %struct.rtvec_def*, %struct.tree_node*, i32, i32, i32, %struct.machine_function*, i32, i32, i8, i8, %struct.language_function*, %struct.rtx_def*, i32, i32, i32, i32, %struct.location_t, %struct.varray_head_tag*, %struct.tree_node*, %struct.tree_node*, i8, i8, i8 }
+ %struct.ht_identifier = type { i8*, i32, i32 }
+ %struct.initial_value_struct = type opaque
+ %struct.lang_decl = type opaque
+ %struct.lang_type = type opaque
+ %struct.language_function = type opaque
+ %struct.location_t = type { i8*, i32 }
+ %struct.loop = type opaque
+ %struct.machine_function = type { %struct.stack_local_entry*, i8*, %struct.rtx_def*, i32, i32, i32, i32, i32 }
+ %struct.mem_attrs = type { i64, %struct.tree_node*, %struct.rtx_def*, %struct.rtx_def*, i32 }
+ %struct.obstack = type { i64, %struct._obstack_chunk*, i8*, i8*, i8*, i64, i32, %struct._obstack_chunk* (i8*, i64)*, void (i8*, %struct._obstack_chunk*)*, i8*, i8 }
+ %struct.phi_arg_d = type { %struct.tree_node*, i8 }
+ %struct.ptr_info_def = type opaque
+ %struct.real_value = type opaque
+ %struct.reg_attrs = type { %struct.tree_node*, i64 }
+ %struct.reg_info_def = type { i32, i32, i32, i32, i32, i32, i32, i32, i32 }
+ %struct.reorder_block_def = type { %struct.rtx_def*, %struct.rtx_def*, %struct.basic_block_def*, %struct.basic_block_def*, %struct.basic_block_def*, i32, i32, i32 }
+ %struct.rtunion = type { i8* }
+ %struct.rtvec_def = type { i32, [1 x %struct.rtx_def*] }
+ %struct.rtx_def = type { i16, i8, i8, %struct.u }
+ %struct.sequence_stack = type { %struct.rtx_def*, %struct.rtx_def*, %struct.sequence_stack* }
+ %struct.simple_bitmap_def = type { i32, i32, i32, [1 x i64] }
+ %struct.stack_local_entry = type opaque
+ %struct.temp_slot = type opaque
+ %struct.tree_binfo = type { %struct.tree_common, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.VEC_tree*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.VEC_tree }
+ %struct.tree_block = type { %struct.tree_common, i32, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node* }
+ %struct.tree_common = type { %struct.tree_node*, %struct.tree_node*, %union.tree_ann_d*, i8, i8, i8, i8, i8 }
+ %struct.tree_complex = type { %struct.tree_common, %struct.tree_node*, %struct.tree_node* }
+ %struct.tree_decl = type { %struct.tree_common, %struct.location_t, i32, %struct.tree_node*, i8, i8, i8, i8, i8, i8, i8, i8, i32, %struct.tree_decl_u1, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.rtx_def*, i32, %struct.tree_decl_u2, %struct.tree_node*, %struct.tree_node*, i64, %struct.lang_decl* }
+ %struct.tree_decl_u1 = type { i64 }
+ %struct.tree_decl_u1_a = type <{ i32 }>
+ %struct.tree_decl_u2 = type { %struct.function* }
+ %struct.tree_exp = type { %struct.tree_common, %struct.location_t*, i32, %struct.tree_node*, [1 x %struct.tree_node*] }
+ %struct.tree_identifier = type { %struct.tree_common, %struct.ht_identifier }
+ %struct.tree_int_cst = type { %struct.tree_common, %struct.tree_int_cst_lowhi }
+ %struct.tree_int_cst_lowhi = type { i64, i64 }
+ %struct.tree_list = type { %struct.tree_common, %struct.tree_node*, %struct.tree_node* }
+ %struct.tree_node = type { %struct.tree_decl }
+ %struct.tree_phi_node = type { %struct.tree_common, %struct.tree_node*, i32, i32, i32, %struct.basic_block_def*, %struct.dataflow_d*, [1 x %struct.phi_arg_d] }
+ %struct.tree_real_cst = type { %struct.tree_common, %struct.real_value* }
+ %struct.tree_ssa_name = type { %struct.tree_common, %struct.tree_node*, i32, %struct.ptr_info_def*, %struct.tree_node*, i8* }
+ %struct.tree_statement_list = type { %struct.tree_common, %struct.tree_statement_list_node*, %struct.tree_statement_list_node* }
+ %struct.tree_statement_list_node = type { %struct.tree_statement_list_node*, %struct.tree_statement_list_node*, %struct.tree_node* }
+ %struct.tree_string = type { %struct.tree_common, i32, [1 x i8] }
+ %struct.tree_type = type { %struct.tree_common, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, i32, i16, i8, i8, i32, %struct.tree_node*, %struct.tree_node*, %struct.rtunion, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, i64, %struct.lang_type* }
+ %struct.tree_type_symtab = type { i8* }
+ %struct.tree_value_handle = type { %struct.tree_common, %struct.value_set*, i32 }
+ %struct.tree_vec = type { %struct.tree_common, i32, [1 x %struct.tree_node*] }
+ %struct.tree_vector = type { %struct.tree_common, %struct.tree_node* }
+ %struct.u = type { [1 x %struct.rtunion] }
+ %struct.value_set = type opaque
+ %struct.var_refs_queue = type { %struct.rtx_def*, i32, i32, %struct.var_refs_queue* }
+ %struct.varasm_status = type opaque
+ %struct.varray_data = type { [1 x i64] }
+ %struct.varray_head_tag = type { i64, i64, i32, i8*, %struct.varray_data }
+ %union.tree_ann_d = type opaque
+ at first_edge_aux_obj = external global i8* ; [#uses=0]
+ at first_block_aux_obj = external global i8* ; [#uses=0]
+ at n_edges = external global i32 ; [#uses=0]
+ at ENTRY_BLOCK_PTR = external global %struct.basic_block_def* ; <%struct.basic_block_def**> [#uses=0]
+ at EXIT_BLOCK_PTR = external global %struct.basic_block_def* ; <%struct.basic_block_def**> [#uses=0]
+ at n_basic_blocks = external global i32 ; [#uses=0]
+ at .str = external constant [9 x i8] ; <[9 x i8]*> [#uses=0]
+ at rbi_pool = external global %struct.alloc_pool_def* ; <%struct.alloc_pool_def**> [#uses=0]
+ at __FUNCTION__.19643 = external constant [18 x i8] ; <[18 x i8]*> [#uses=0]
+ at .str1 = external constant [20 x i8] ; <[20 x i8]*> [#uses=0]
+ at __FUNCTION__.19670 = external constant [15 x i8] ; <[15 x i8]*> [#uses=0]
+ at basic_block_info = external global %struct.varray_head_tag* ; <%struct.varray_head_tag**> [#uses=0]
+ at last_basic_block = external global i32 ; [#uses=0]
+ at __FUNCTION__.19696 = external constant [14 x i8] ; <[14 x i8]*> [#uses=0]
+ at __FUNCTION__.20191 = external constant [20 x i8] ; <[20 x i8]*> [#uses=0]
+ at block_aux_obstack = external global %struct.obstack ; <%struct.obstack*> [#uses=0]
+ at __FUNCTION__.20301 = external constant [20 x i8] ; <[20 x i8]*> [#uses=0]
+ at __FUNCTION__.20316 = external constant [19 x i8] ; <[19 x i8]*> [#uses=0]
+ at edge_aux_obstack = external global %struct.obstack ; <%struct.obstack*> [#uses=0]
+ at stderr = external global %struct._IO_FILE* ; <%struct._IO_FILE**> [#uses=0]
+ at __FUNCTION__.20463 = external constant [11 x i8] ; <[11 x i8]*> [#uses=0]
+ at .str2 = external constant [7 x i8] ; <[7 x i8]*> [#uses=0]
+ at .str3 = external constant [6 x i8] ; <[6 x i8]*> [#uses=0]
+ at .str4 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+ at .str5 = external constant [11 x i8] ; <[11 x i8]*> [#uses=0]
+ at .str6 = external constant [8 x i8] ; <[8 x i8]*> [#uses=0]
+ at .str7 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+ at bitnames.20157 = external constant [13 x i8*] ; <[13 x i8*]*> [#uses=0]
+ at .str8 = external constant [9 x i8] ; <[9 x i8]*> [#uses=0]
+ at .str9 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+ at .str10 = external constant [7 x i8] ; <[7 x i8]*> [#uses=0]
+ at .str11 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+ at .str12 = external constant [5 x i8] ; <[5 x i8]*> [#uses=0]
+ at .str13 = external constant [9 x i8] ; <[9 x i8]*> [#uses=0]
+ at .str14 = external constant [13 x i8] ; <[13 x i8]*> [#uses=0]
+ at .str15 = external constant [12 x i8] ; <[12 x i8]*> [#uses=0]
+ at .str16 = external constant [8 x i8] ; <[8 x i8]*> [#uses=0]
+ at .str17 = external constant [10 x i8] ; <[10 x i8]*> [#uses=0]
+ at .str18 = external constant [5 x i8] ; <[5 x i8]*> [#uses=0]
+ at .str19 = external constant [6 x i8] ; <[6 x i8]*> [#uses=0]
+ at .str20 = external constant [5 x i8] ; <[5 x i8]*> [#uses=0]
+ at .str21 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+ at .str22 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+ at __FUNCTION__.19709 = external constant [20 x i8] ; <[20 x i8]*> [#uses=0]
+ at .str23 = external constant [5 x i8] ; <[5 x i8]*> [#uses=0]
+ at .str24 = external constant [10 x i8] ; <[10 x i8]*> [#uses=0]
+ at __FUNCTION__.19813 = external constant [19 x i8] ; <[19 x i8]*> [#uses=0]
+ at .str25 = external constant [7 x i8] ; <[7 x i8]*> [#uses=0]
+ at .str26 = external constant [6 x i8] ; <[6 x i8]*> [#uses=0]
+ at initialized.20241.b = external global i1 ; [#uses=0]
+ at __FUNCTION__.20244 = external constant [21 x i8] ; <[21 x i8]*> [#uses=0]
+ at __FUNCTION__.19601 = external constant [12 x i8] ; <[12 x i8]*> [#uses=0]
+ at __FUNCTION__.14571 = external constant [8 x i8] ; <[8 x i8]*> [#uses=0]
+ at __FUNCTION__.14535 = external constant [13 x i8] ; <[13 x i8]*> [#uses=0]
+ at .str27 = external constant [28 x i8] ; <[28 x i8]*> [#uses=0]
+ at __FUNCTION__.14589 = external constant [8 x i8] ; <[8 x i8]*> [#uses=0]
+ at __FUNCTION__.19792 = external constant [12 x i8] ; <[12 x i8]*> [#uses=0]
+ at __FUNCTION__.19851 = external constant [19 x i8] ; <[19 x i8]*> [#uses=0]
+ at profile_status = external global i32 ; [#uses=0]
+ at .str29 = external constant [46 x i8] ; <[46 x i8]*> [#uses=0]
+ at .str30 = external constant [49 x i8] ; <[49 x i8]*> [#uses=0]
+ at .str31 = external constant [54 x i8] ; <[54 x i8]*> [#uses=0]
+ at .str32 = external constant [49 x i8] ; <[49 x i8]*> [#uses=1]
+ at __FUNCTION__.19948 = external constant [15 x i8] ; <[15 x i8]*> [#uses=0]
+ at reg_n_info = external global %struct.varray_head_tag* ; <%struct.varray_head_tag**> [#uses=0]
+ at reload_completed = external global i32 ; [#uses=0]
+ at .str33 = external constant [15 x i8] ; <[15 x i8]*> [#uses=0]
+ at .str34 = external constant [43 x i8] ; <[43 x i8]*> [#uses=0]
+ at .str35 = external constant [13 x i8] ; <[13 x i8]*> [#uses=0]
+ at .str36 = external constant [1 x i8] ; <[1 x i8]*> [#uses=0]
+ at .str37 = external constant [2 x i8] ; <[2 x i8]*> [#uses=0]
+ at .str38 = external constant [16 x i8] ; <[16 x i8]*> [#uses=0]
+ at cfun = external global %struct.function* ; <%struct.function**> [#uses=0]
+ at .str39 = external constant [14 x i8] ; <[14 x i8]*> [#uses=0]
+ at .str40 = external constant [11 x i8] ; <[11 x i8]*> [#uses=0]
+ at .str41 = external constant [20 x i8] ; <[20 x i8]*> [#uses=0]
+ at .str42 = external constant [17 x i8] ; <[17 x i8]*> [#uses=0]
+ at .str43 = external constant [19 x i8] ; <[19 x i8]*> [#uses=0]
+ at mode_size = external global [48 x i8] ; <[48 x i8]*> [#uses=0]
+ at target_flags = external global i32 ; [#uses=0]
+ at .str44 = external constant [11 x i8] ; <[11 x i8]*> [#uses=0]
+ at reg_class_names = external global [0 x i8*] ; <[0 x i8*]*> [#uses=0]
+ at .str45 = external constant [10 x i8] ; <[10 x i8]*> [#uses=0]
+ at .str46 = external constant [13 x i8] ; <[13 x i8]*> [#uses=0]
+ at .str47 = external constant [19 x i8] ; <[19 x i8]*> [#uses=0]
+ at .str48 = external constant [12 x i8] ; <[12 x i8]*> [#uses=0]
+ at .str49 = external constant [10 x i8] ; <[10 x i8]*> [#uses=0]
+ at .str50 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+ at .str51 = external constant [29 x i8] ; <[29 x i8]*> [#uses=0]
+ at .str52 = external constant [17 x i8] ; <[17 x i8]*> [#uses=0]
+ at .str53 = external constant [19 x i8] ; <[19 x i8]*> [#uses=0]
+ at .str54 = external constant [22 x i8] ; <[22 x i8]*> [#uses=0]
+ at .str55 = external constant [10 x i8] ; <[10 x i8]*> [#uses=0]
+ at .str56 = external constant [12 x i8] ; <[12 x i8]*> [#uses=0]
+ at .str57 = external constant [26 x i8] ; <[26 x i8]*> [#uses=0]
+ at .str58 = external constant [15 x i8] ; <[15 x i8]*> [#uses=0]
+ at .str59 = external constant [14 x i8] ; <[14 x i8]*> [#uses=0]
+ at .str60 = external constant [26 x i8] ; <[26 x i8]*> [#uses=0]
+ at .str61 = external constant [24 x i8] ; <[24 x i8]*> [#uses=0]
+ at initialized.20366.b = external global i1 ; [#uses=0]
+ at __FUNCTION__.20369 = external constant [20 x i8] ; <[20 x i8]*> [#uses=0]
+ at __FUNCTION__.20442 = external constant [19 x i8] ; <[19 x i8]*> [#uses=0]
+ at bb_bitnames.20476 = external constant [6 x i8*] ; <[6 x i8*]*> [#uses=0]
+ at .str62 = external constant [6 x i8] ; <[6 x i8]*> [#uses=0]
+ at .str63 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+ at .str64 = external constant [10 x i8] ; <[10 x i8]*> [#uses=0]
+ at .str65 = external constant [8 x i8] ; <[8 x i8]*> [#uses=0]
+ at .str66 = external constant [17 x i8] ; <[17 x i8]*> [#uses=0]
+ at .str67 = external constant [11 x i8] ; <[11 x i8]*> [#uses=0]
+ at .str68 = external constant [15 x i8] ; <[15 x i8]*> [#uses=0]
+ at .str69 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+ at .str70 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+ at __FUNCTION__.20520 = external constant [32 x i8] ; <[32 x i8]*> [#uses=0]
+ at dump_file = external global %struct._IO_FILE* ; <%struct._IO_FILE**> [#uses=0]
+ at .str71 = external constant [86 x i8] ; <[86 x i8]*> [#uses=0]
+ at .str72 = external constant [94 x i8] ; <[94 x i8]*> [#uses=0]
+ at reg_obstack = external global %struct.bitmap_obstack ; <%struct.bitmap_obstack*> [#uses=0]
+
+declare void @init_flow()
+
+declare i8* @ggc_alloc_cleared_stat(i64)
+
+declare fastcc void @free_edge(%struct.edge_def*)
+
+declare void @ggc_free(i8*)
+
+declare %struct.basic_block_def* @alloc_block()
+
+declare void @alloc_rbi_pool()
+
+declare %struct.alloc_pool_def* @create_alloc_pool(i8*, i64, i64)
+
+declare void @free_rbi_pool()
+
+declare void @free_alloc_pool(%struct.alloc_pool_def*)
+
+declare void @initialize_bb_rbi(%struct.basic_block_def*)
+
+declare void @fancy_abort(i8*, i32, i8*)
+
+declare i8* @pool_alloc(%struct.alloc_pool_def*)
+
+declare void @llvm.memset.i64(i8*, i8, i64, i32)
+
+declare void @link_block(%struct.basic_block_def*, %struct.basic_block_def*)
+
+declare void @unlink_block(%struct.basic_block_def*)
+
+declare void @compact_blocks()
+
+declare void @varray_check_failed(%struct.varray_head_tag*, i64, i8*, i32, i8*)
+
+declare void @expunge_block(%struct.basic_block_def*)
+
+declare void @clear_bb_flags()
+
+declare void @alloc_aux_for_block(%struct.basic_block_def*, i32)
+
+declare void @_obstack_newchunk(%struct.obstack*, i32)
+
+declare void @clear_aux_for_blocks()
+
+declare void @free_aux_for_blocks()
+
+declare void @obstack_free(%struct.obstack*, i8*)
+
+declare void @alloc_aux_for_edge(%struct.edge_def*, i32)
+
+declare void @debug_bb(%struct.basic_block_def*)
+
+declare void @dump_bb(%struct.basic_block_def*, %struct._IO_FILE*, i32)
+
+declare %struct.basic_block_def* @debug_bb_n(i32)
+
+declare void @dump_edge_info(%struct._IO_FILE*, %struct.edge_def*, i32)
+
+declare i32 @fputs_unlocked(i8* noalias , %struct._IO_FILE* noalias )
+
+declare i32 @fprintf(%struct._IO_FILE* noalias , i8* noalias , ...)
+
+declare i64 @fwrite(i8*, i64, i64, i8*)
+
+declare i32 @__overflow(%struct._IO_FILE*, i32)
+
+declare %struct.edge_def* @unchecked_make_edge(%struct.basic_block_def*, %struct.basic_block_def*, i32)
+
+declare i8* @vec_gc_p_reserve(i8*, i32)
+
+declare void @vec_assert_fail(i8*, i8*, i8*, i32, i8*)
+
+declare void @execute_on_growing_pred(%struct.edge_def*)
+
+declare %struct.edge_def* @make_edge(%struct.basic_block_def*, %struct.basic_block_def*, i32)
+
+declare %struct.edge_def* @find_edge(%struct.basic_block_def*, %struct.basic_block_def*)
+
+declare %struct.edge_def* @make_single_succ_edge(%struct.basic_block_def*, %struct.basic_block_def*, i32)
+
+declare %struct.edge_def* @cached_make_edge(%struct.simple_bitmap_def**, %struct.basic_block_def*, %struct.basic_block_def*, i32)
+
+declare void @redirect_edge_succ(%struct.edge_def*, %struct.basic_block_def*)
+
+declare void @execute_on_shrinking_pred(%struct.edge_def*)
+
+declare void @alloc_aux_for_blocks(i32)
+
+declare i8* @xmalloc(i64)
+
+declare i32 @_obstack_begin(%struct.obstack*, i32, i32, i8* (i64)*, void (i8*)*)
+
+declare void @free(i8*)
+
+declare void @clear_edges()
+
+declare void @remove_edge(%struct.edge_def*)
+
+declare %struct.edge_def* @redirect_edge_succ_nodup(%struct.edge_def*, %struct.basic_block_def*)
+
+declare void @redirect_edge_pred(%struct.edge_def*, %struct.basic_block_def*)
+
+define void @check_bb_profile(%struct.basic_block_def* %bb, %struct._IO_FILE* %file) {
+entry:
+ br i1 false, label %cond_false759.preheader, label %cond_false149.preheader
+
+cond_false149.preheader: ; preds = %entry
+ ret void
+
+cond_false759.preheader: ; preds = %entry
+ br i1 false, label %cond_next873, label %cond_true794
+
+bb644: ; preds = %cond_next873
+ ret void
+
+cond_true794: ; preds = %cond_false759.preheader
+ ret void
+
+cond_next873: ; preds = %cond_false759.preheader
+ br i1 false, label %bb882, label %bb644
+
+bb882: ; preds = %cond_next873
+ br i1 false, label %cond_true893, label %cond_next901
+
+cond_true893: ; preds = %bb882
+ br label %cond_false1036
+
+cond_next901: ; preds = %bb882
+ ret void
+
+bb929: ; preds = %cond_next1150
+ %tmp934 = add i64 0, %lsum.11225.0 ; [#uses=1]
+ br i1 false, label %cond_next979, label %cond_true974
+
+cond_true974: ; preds = %bb929
+ ret void
+
+cond_next979: ; preds = %bb929
+ br label %cond_false1036
+
+cond_false1036: ; preds = %cond_next979, %cond_true893
+ %lsum.11225.0 = phi i64 [ 0, %cond_true893 ], [ %tmp934, %cond_next979 ] ; [#uses=2]
+ br i1 false, label %cond_next1056, label %cond_true1051
+
+cond_true1051: ; preds = %cond_false1036
+ ret void
+
+cond_next1056: ; preds = %cond_false1036
+ br i1 false, label %cond_next1150, label %cond_true1071
+
+cond_true1071: ; preds = %cond_next1056
+ ret void
+
+cond_next1150: ; preds = %cond_next1056
+ %tmp1156 = icmp eq %struct.edge_def* null, null ; [#uses=1]
+ br i1 %tmp1156, label %bb1159, label %bb929
+
+bb1159: ; preds = %cond_next1150
+ br i1 false, label %cond_true1169, label %UnifiedReturnBlock
+
+cond_true1169: ; preds = %bb1159
+ %tmp11741175 = trunc i64 %lsum.11225.0 to i32 ; [#uses=1]
+ %tmp1178 = tail call i32 (%struct._IO_FILE* noalias , i8* noalias , ...)* @fprintf( %struct._IO_FILE* %file noalias , i8* getelementptr ([49 x i8]* @.str32, i32 0, i64 0) noalias , i32 %tmp11741175, i32 0 ) ; [#uses=0]
+ ret void
+
+UnifiedReturnBlock: ; preds = %bb1159
+ ret void
+}
+
+declare void @dump_flow_info(%struct._IO_FILE*)
+
+declare i32 @max_reg_num()
+
+declare void @rtl_check_failed_flag(i8*, %struct.rtx_def*, i8*, i32, i8*)
+
+declare i32 @reg_preferred_class(i32)
+
+declare i32 @reg_alternate_class(i32)
+
+declare i8 @maybe_hot_bb_p(%struct.basic_block_def*) zeroext
+
+declare i8 @probably_never_executed_bb_p(%struct.basic_block_def*) zeroext
+
+declare void @dump_regset(%struct.bitmap_head_def*, %struct._IO_FILE*)
+
+declare void @debug_flow_info()
+
+declare void @alloc_aux_for_edges(i32)
+
+declare void @clear_aux_for_edges()
+
+declare void @free_aux_for_edges()
+
+declare void @brief_dump_cfg(%struct._IO_FILE*)
+
+declare i32 @fputc(i32, i8*)
+
+declare void @update_bb_profile_for_threading(%struct.basic_block_def*, i32, i64, %struct.edge_def*)
From dalej at apple.com Mon Oct 15 13:42:17 2007
From: dalej at apple.com (Dale Johannesen)
Date: Mon, 15 Oct 2007 18:42:17 -0000
Subject: [llvm-commits] [llvm-gcc-4.0] r42997 -
/llvm-gcc-4.0/trunk/gcc/config/rs6000/rs6000.c
Message-ID: <200710151842.l9FIgHj6006655@zion.cs.uiuc.edu>
Author: johannes
Date: Mon Oct 15 13:42:17 2007
New Revision: 42997
URL: http://llvm.org/viewvc/llvm-project?rev=42997&view=rev
Log:
Set modes for Altivec bool and pixel types. From vecLib.
Modified:
llvm-gcc-4.0/trunk/gcc/config/rs6000/rs6000.c
Modified: llvm-gcc-4.0/trunk/gcc/config/rs6000/rs6000.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/config/rs6000/rs6000.c?rev=42997&r1=42996&r2=42997&view=diff
==============================================================================
--- llvm-gcc-4.0/trunk/gcc/config/rs6000/rs6000.c (original)
+++ llvm-gcc-4.0/trunk/gcc/config/rs6000/rs6000.c Mon Oct 15 13:42:17 2007
@@ -9161,22 +9161,6 @@
unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
- /* APPLE LOCAL begin LLVM */
-#ifdef ENABLE_LLVM
- /* LLVM doesn't initialize the RTL backend, so build_vector_type will assign
- all of these types BLKmode. This interferes with rs6000.c-specific
- handling of -faltivec overloads (an apple local patch). As such, give them
- the correct modes here manually. */
- TYPE_MODE (V4SI_type_node) = V4SImode;
- TYPE_MODE (V4SF_type_node) = V4SFmode;
- TYPE_MODE (V8HI_type_node) = V8HImode;
- TYPE_MODE (V16QI_type_node) = V16QImode;
- TYPE_MODE (unsigned_V4SI_type_node) = V4SImode;
- TYPE_MODE (unsigned_V8HI_type_node) = V8HImode;
- TYPE_MODE (unsigned_V16QI_type_node) = V16QImode;
-#endif
- /* APPLE LOCAL end LLVM */
-
opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
@@ -9208,6 +9192,26 @@
bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
+ /* APPLE LOCAL begin LLVM */
+#ifdef ENABLE_LLVM
+ /* LLVM doesn't initialize the RTL backend, so build_vector_type will assign
+ all of these types BLKmode. This interferes with rs6000.c-specific
+ handling of -faltivec overloads (an apple local patch). As such, give them
+ the correct modes here manually. */
+ TYPE_MODE (V4SI_type_node) = V4SImode;
+ TYPE_MODE (V4SF_type_node) = V4SFmode;
+ TYPE_MODE (V8HI_type_node) = V8HImode;
+ TYPE_MODE (V16QI_type_node) = V16QImode;
+ TYPE_MODE (unsigned_V4SI_type_node) = V4SImode;
+ TYPE_MODE (unsigned_V8HI_type_node) = V8HImode;
+ TYPE_MODE (unsigned_V16QI_type_node) = V16QImode;
+ TYPE_MODE (bool_V16QI_type_node) = V16QImode;
+ TYPE_MODE (bool_V8HI_type_node) = V8HImode;
+ TYPE_MODE (bool_V4SI_type_node) = V4SImode;
+ TYPE_MODE (pixel_V8HI_type_node) = V8HImode;
+#endif
+ /* APPLE LOCAL end LLVM */
+
(*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
get_identifier ("__vector unsigned char"),
unsigned_V16QI_type_node));
From kremenek at apple.com Mon Oct 15 13:52:34 2007
From: kremenek at apple.com (Ted Kremenek)
Date: Mon, 15 Oct 2007 18:52:34 -0000
Subject: [llvm-commits] [llvm] r42998 -
/llvm/trunk/include/llvm/ADT/ImmutableSet.h
Message-ID: <200710151852.l9FIqY9p007090@zion.cs.uiuc.edu>
Author: kremenek
Date: Mon Oct 15 13:52:34 2007
New Revision: 42998
URL: http://llvm.org/viewvc/llvm-project?rev=42998&view=rev
Log:
Added more doxygen comments.
Renamed internal method of ImutAVLTree::RemoveMutableFlag to MarkImmutable.
Added enum for bit manipulation (more self-documentating).
Modified:
llvm/trunk/include/llvm/ADT/ImmutableSet.h
Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=42998&r1=42997&r2=42998&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original)
+++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Mon Oct 15 13:52:34 2007
@@ -198,7 +198,12 @@
//===----------------------------------------------------===//
// Profiling or FoldingSet.
//===----------------------------------------------------===//
-
+
+private:
+
+ /// Profile - Generates a FoldingSet profile for a tree node before it is
+ /// created. This is used by the ImutAVLFactory when creating
+ /// trees.
static inline
void Profile(FoldingSetNodeID& ID, ImutAVLTree* L, ImutAVLTree* R,
value_type_ref V) {
@@ -208,7 +213,8 @@
}
public:
-
+
+ /// Profile - Generates a FoldingSet profile for an existing tree node.
void Profile(FoldingSetNodeID& ID) {
Profile(ID,getSafeLeft(),getRight(),getValue());
}
@@ -219,41 +225,72 @@
private:
+ enum { Mutable = 0x1 };
+
+ /// ImutAVLTree - Internal constructor that is only called by
+ /// ImutAVLFactory.
ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, unsigned height)
- : Left(reinterpret_cast(l) | 0x1),
+ : Left(reinterpret_cast(l) | Mutable),
Right(r), Height(height), Value(v) {}
- bool isMutable() const { return Left & 0x1; }
+ /// isMutable - Returns true if the left and right subtree references
+ /// (as well as height) can be changed. If this method returns false,
+ /// the tree is truly immutable. Trees returned from an ImutAVLFactory
+ /// object should always have this method return true. Further, if this
+ /// method returns false for an instance of ImutAVLTree, all subtrees
+ /// will also have this method return false. The converse is not true.
+ bool isMutable() const { return Left & Mutable; }
+
+ /// getSafeLeft - Returns the pointer to the left tree by always masking
+ /// out the mutable bit. This is used internally by ImutAVLFactory,
+ /// as no trees returned to the client should have the mutable flag set.
ImutAVLTree* getSafeLeft() const {
- return reinterpret_cast(Left & ~0x1);
+ return reinterpret_cast(Left & ~Mutable);
}
- // Mutating operations. A tree root can be manipulated as long as
- // its reference has not "escaped" from internal methods of a
- // factory object (see below). When a tree pointer is externally
- // viewable by client code, the internal "mutable bit" is cleared
- // to mark the tree immutable. Note that a tree that still has
- // its mutable bit set may have children (subtrees) that are themselves
+ //===----------------------------------------------------===//
+ // Mutating operations. A tree root can be manipulated as
+ // long as its reference has not "escaped" from internal
+ // methods of a factory object (see below). When a tree
+ // pointer is externally viewable by client code, the
+ // internal "mutable bit" is cleared to mark the tree
+ // immutable. Note that a tree that still has its mutable
+ // bit set may have children (subtrees) that are themselves
// immutable.
+ //===----------------------------------------------------===//
- void RemoveMutableFlag() {
- assert (Left & 0x1 && "Mutable flag already removed.");
- Left &= ~0x1;
+
+ /// MarkImmutable - Clears the mutable flag for a tree. After this happens,
+ /// it is an error to call setLeft(), setRight(), and setHeight(). It
+ /// is also then safe to call getLeft() instead of getSafeLeft().
+ void MarkMutable() {
+ assert (isMutable() && "Mutable flag already removed.");
+ Left &= ~Mutable;
}
+ /// setLeft - Changes the reference of the left subtree. Used internally
+ /// by ImutAVLFactory.
void setLeft(ImutAVLTree* NewLeft) {
- assert (isMutable());
- Left = reinterpret_cast(NewLeft) | 0x1;
+ assert (isMutable() &&
+ "Only a mutable tree can have its left subtree changed.");
+
+ Left = reinterpret_cast(NewLeft) | Mutable;
}
+ /// setRight - Changes the reference of the right subtree. Used internally
+ /// by ImutAVLFactory.
void setRight(ImutAVLTree* NewRight) {
- assert (isMutable());
+ assert (isMutable() &&
+ "Only a mutable tree can have its right subtree changed.");
+
Right = NewRight;
}
+ /// setHeight - Changes the height of the tree. Used internally by
+ /// ImutAVLFactory.
void setHeight(unsigned h) {
- assert (isMutable());
+ assert (isMutable() && "Only a mutable tree can have its height changed.");
Height = h;
}
};
@@ -470,7 +507,7 @@
if (!T || !T->isMutable())
return;
- T->RemoveMutableFlag();
+ T->MarkMutable();
MarkImmutable(Left(T));
MarkImmutable(Right(T));
}
From kremenek at apple.com Mon Oct 15 14:15:48 2007
From: kremenek at apple.com (Ted Kremenek)
Date: Mon, 15 Oct 2007 19:15:48 -0000
Subject: [llvm-commits] [llvm] r42999 -
/llvm/trunk/include/llvm/ADT/ImmutableSet.h
Message-ID: <200710151915.l9FJFmHx008213@zion.cs.uiuc.edu>
Author: kremenek
Date: Mon Oct 15 14:15:48 2007
New Revision: 42999
URL: http://llvm.org/viewvc/llvm-project?rev=42999&view=rev
Log:
Fixed incorrect renaming of method name (forgot two characters).
Modified:
llvm/trunk/include/llvm/ADT/ImmutableSet.h
Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=42999&r1=42998&r2=42999&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original)
+++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Mon Oct 15 14:15:48 2007
@@ -264,7 +264,7 @@
/// MarkImmutable - Clears the mutable flag for a tree. After this happens,
/// it is an error to call setLeft(), setRight(), and setHeight(). It
/// is also then safe to call getLeft() instead of getSafeLeft().
- void MarkMutable() {
+ void MarkImmutable() {
assert (isMutable() && "Mutable flag already removed.");
Left &= ~Mutable;
}
@@ -507,7 +507,7 @@
if (!T || !T->isMutable())
return;
- T->MarkMutable();
+ T->MarkImmutable();
MarkImmutable(Left(T));
MarkImmutable(Right(T));
}
From djg at cray.com Mon Oct 15 14:22:17 2007
From: djg at cray.com (Dan Gohman)
Date: Mon, 15 Oct 2007 19:22:17 -0000
Subject: [llvm-commits] [llvm] r43001 -
/llvm/trunk/test/CodeGen/X86/fp_constant_op.llx
Message-ID: <200710151922.l9FJMHak008591@zion.cs.uiuc.edu>
Author: djg
Date: Mon Oct 15 14:22:17 2007
New Revision: 43001
URL: http://llvm.org/viewvc/llvm-project?rev=43001&view=rev
Log:
Reapply the fix in 42908 for this file. This changes the function names
from "test" to "foo" so that they don't match the grep -i ST.
Modified:
llvm/trunk/test/CodeGen/X86/fp_constant_op.llx
Modified: llvm/trunk/test/CodeGen/X86/fp_constant_op.llx
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fp_constant_op.llx?rev=43001&r1=43000&r2=43001&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fp_constant_op.llx (original)
+++ llvm/trunk/test/CodeGen/X86/fp_constant_op.llx Mon Oct 15 14:22:17 2007
@@ -3,32 +3,32 @@
; Test that the load of the constant is folded into the operation.
-double %test_add(double %P) {
+double %foo_add(double %P) {
%tmp.1 = add double %P, 0x405EC00000000000
ret double %tmp.1
}
-double %test_mul(double %P) {
+double %foo_mul(double %P) {
%tmp.1 = mul double %P, 0x405EC00000000000
ret double %tmp.1
}
-double %test_sub(double %P) {
+double %foo_sub(double %P) {
%tmp.1 = sub double %P, 0x405EC00000000000
ret double %tmp.1
}
-double %test_subr(double %P) {
+double %foo_subr(double %P) {
%tmp.1 = sub double 0x405EC00000000000, %P
ret double %tmp.1
}
-double %test_div(double %P) {
+double %foo_div(double %P) {
%tmp.1 = div double %P, 0x405EC00000000000
ret double %tmp.1
}
-double %test_divr(double %P) {
+double %foo_divr(double %P) {
%tmp.1 = div double 0x405EC00000000000, %P
ret double %tmp.1
}
From dpatel at apple.com Mon Oct 15 14:56:32 2007
From: dpatel at apple.com (Devang Patel)
Date: Mon, 15 Oct 2007 19:56:32 -0000
Subject: [llvm-commits] [llvm] r43002 - in /llvm/trunk:
include/llvm/ExecutionEngine/ExecutionEngine.h
lib/ExecutionEngine/ExecutionEngine.cpp
Message-ID: <200710151956.l9FJuWNC010761@zion.cs.uiuc.edu>
Author: dpatel
Date: Mon Oct 15 14:56:32 2007
New Revision: 43002
URL: http://llvm.org/viewvc/llvm-project?rev=43002&view=rev
Log:
Add removeModuleProvider()
Modified:
llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h
llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=43002&r1=43001&r2=43002&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Mon Oct 15 14:56:32 2007
@@ -97,7 +97,11 @@
void addModuleProvider(ModuleProvider *P) {
Modules.push_back(P);
}
-
+
+ /// removeModuleProvider - Remove a ModuleProvider from the list of modules.
+ /// Release module from ModuleProvider.
+ Module* removeModuleProvider(ModuleProvider *P, std::string *ErrInfo = 0);
+
/// FindFunctionNamed - Search all of the active modules to find the one that
/// defines FnName. This is very slow operation and shouldn't be used for
/// general code.
Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=43002&r1=43001&r2=43002&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Mon Oct 15 14:56:32 2007
@@ -51,6 +51,21 @@
delete Modules[i];
}
+/// removeModuleProvider - Remove a ModuleProvider from the list of modules.
+/// Release module from ModuleProvider.
+Module* ExecutionEngine::removeModuleProvider(ModuleProvider *P,
+ std::string *ErrInfo) {
+ for(SmallVector::iterator I = Modules.begin(),
+ E = Modules.end(); I != E; ++I) {
+ ModuleProvider *MP = *I;
+ if (MP == P) {
+ Modules.erase(I);
+ return MP->releaseModule(ErrInfo);
+ }
+ }
+ return NULL;
+}
+
/// FindFunctionNamed - Search all of the active modules to find the one that
/// defines FnName. This is very slow operation and shouldn't be used for
/// general code.
From dalej at apple.com Mon Oct 15 15:03:01 2007
From: dalej at apple.com (Dale Johannesen)
Date: Mon, 15 Oct 2007 20:03:01 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r43003 -
/llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c
Message-ID: <200710152003.l9FK31JS011088@zion.cs.uiuc.edu>
Author: johannes
Date: Mon Oct 15 15:03:00 2007
New Revision: 43003
URL: http://llvm.org/viewvc/llvm-project?rev=43003&view=rev
Log:
Set modes for bool and pixel Altivec types.
Modified:
llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c
Modified: llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c?rev=43003&r1=43002&r2=43003&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c (original)
+++ llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c Mon Oct 15 15:03:00 2007
@@ -9077,22 +9077,6 @@
unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
- /* LLVM LOCAL begin */
-#ifdef ENABLE_LLVM
- /* LLVM doesn't initialize the RTL backend, so build_vector_type will assign
- all of these types BLKmode. This interferes with rs6000.c-specific
- handling of -faltivec overloads (an apple local patch). As such, give them
- the correct modes here manually. */
- TYPE_MODE (V4SI_type_node) = V4SImode;
- TYPE_MODE (V4SF_type_node) = V4SFmode;
- TYPE_MODE (V8HI_type_node) = V8HImode;
- TYPE_MODE (V16QI_type_node) = V16QImode;
- TYPE_MODE (unsigned_V4SI_type_node) = V4SImode;
- TYPE_MODE (unsigned_V8HI_type_node) = V8HImode;
- TYPE_MODE (unsigned_V16QI_type_node) = V16QImode;
-#endif
- /* LLVM LOCAL end */
-
opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
@@ -9107,6 +9091,26 @@
bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
+ /* APPLE LOCAL begin LLVM */
+#ifdef ENABLE_LLVM
+ /* LLVM doesn't initialize the RTL backend, so build_vector_type will assign
+ all of these types BLKmode. This interferes with rs6000.c-specific
+ handling of -faltivec overloads (an apple local patch). As such, give them
+ the correct modes here manually. */
+ TYPE_MODE (V4SI_type_node) = V4SImode;
+ TYPE_MODE (V4SF_type_node) = V4SFmode;
+ TYPE_MODE (V8HI_type_node) = V8HImode;
+ TYPE_MODE (V16QI_type_node) = V16QImode;
+ TYPE_MODE (unsigned_V4SI_type_node) = V4SImode;
+ TYPE_MODE (unsigned_V8HI_type_node) = V8HImode;
+ TYPE_MODE (unsigned_V16QI_type_node) = V16QImode;
+ TYPE_MODE (bool_V16QI_type_node) = V16QImode;
+ TYPE_MODE (bool_V8HI_type_node) = V8HImode;
+ TYPE_MODE (bool_V4SI_type_node) = V4SImode;
+ TYPE_MODE (pixel_V8HI_type_node) = V8HImode;
+#endif
+ /* APPLE LOCAL end LLVM */
+
long_integer_type_internal_node = long_integer_type_node;
long_unsigned_type_internal_node = long_unsigned_type_node;
intQI_type_internal_node = intQI_type_node;
From evan.cheng at apple.com Mon Oct 15 15:11:21 2007
From: evan.cheng at apple.com (Evan Cheng)
Date: Mon, 15 Oct 2007 20:11:21 -0000
Subject: [llvm-commits] [llvm] r43004 - in /llvm/trunk:
lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/fp2sint.ll
Message-ID: <200710152011.l9FKBLX1011439@zion.cs.uiuc.edu>
Author: evancheng
Date: Mon Oct 15 15:11:21 2007
New Revision: 43004
URL: http://llvm.org/viewvc/llvm-project?rev=43004&view=rev
Log:
LowerFP_TO_SINT must not create a stack object if it's not needed.
Added:
llvm/trunk/test/CodeGen/X86/fp2sint.ll
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=43004&r1=43003&r2=43004&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Oct 15 15:11:21 2007
@@ -3895,13 +3895,7 @@
SDOperand X86TargetLowering::LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) {
assert(Op.getValueType() <= MVT::i64 && Op.getValueType() >= MVT::i16 &&
"Unknown FP_TO_SINT to lower!");
- // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary
- // stack slot.
SDOperand Result;
- MachineFunction &MF = DAG.getMachineFunction();
- unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8;
- int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
- SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
// These are really Legal.
if (Op.getValueType() == MVT::i32 &&
@@ -3915,6 +3909,12 @@
Op.getOperand(0).getValueType() != MVT::f80)
return Result;
+ // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary
+ // stack slot.
+ MachineFunction &MF = DAG.getMachineFunction();
+ unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8;
+ int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
+ SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
unsigned Opc;
switch (Op.getValueType()) {
default: assert(0 && "Invalid FP_TO_SINT to lower!");
Added: llvm/trunk/test/CodeGen/X86/fp2sint.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fp2sint.ll?rev=43004&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fp2sint.ll (added)
+++ llvm/trunk/test/CodeGen/X86/fp2sint.ll Mon Oct 15 15:11:21 2007
@@ -0,0 +1,18 @@
+;; LowerFP_TO_SINT should not create a stack object if it's not needed.
+
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | not grep add
+
+define i32 @main(i32 %argc, i8** %argv) {
+cond_false.i.i.i: ; preds = %bb.i5
+ %tmp35.i = load double* null, align 8 ; [#uses=1]
+ %tmp3536.i = fptosi double %tmp35.i to i32 ; [#uses=1]
+ %tmp3536140.i = zext i32 %tmp3536.i to i64 ; [#uses=1]
+ %tmp39.i = load double* null, align 4 ; [#uses=1]
+ %tmp3940.i = fptosi double %tmp39.i to i32 ; [#uses=1]
+ %tmp3940137.i = zext i32 %tmp3940.i to i64 ; [#uses=1]
+ %tmp3940137138.i = shl i64 %tmp3940137.i, 32 ; [#uses=1]
+ %tmp3940137138.ins.i = or i64 %tmp3940137138.i, %tmp3536140.i ; [#uses=1]
+ %tmp95.i.i = trunc i64 %tmp3940137138.ins.i to i32 ; [#uses=1]
+ store i32 %tmp95.i.i, i32* null, align 4
+ ret i32 0
+}
From sabre at nondot.org Mon Oct 15 15:14:53 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 15 Oct 2007 20:14:53 -0000
Subject: [llvm-commits] [llvm] r43005 -
/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
Message-ID: <200710152014.l9FKErXm011603@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Oct 15 15:14:52 2007
New Revision: 43005
URL: http://llvm.org/viewvc/llvm-project?rev=43005&view=rev
Log:
Change LowerFP_TO_SINT to create the specific code it needs instead of
unconditionally creating an i64 bitcast. With the future legalizer
design, operation legalization can't introduce new nodes with illegal
types.
This fixes the rest of olden on ppc32.
Modified:
llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=43005&r1=43004&r2=43005&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Mon Oct 15 15:14:52 2007
@@ -2028,7 +2028,7 @@
DAG.getNode(ISD::FNEG, MVT::f64, LHS), TV, FV);
}
- SDOperand Cmp;
+ SDOperand Cmp;
switch (CC) {
default: break; // SETUO etc aren't handled by fsel.
case ISD::SETULT:
@@ -2081,10 +2081,17 @@
}
// Convert the FP value to an int value through memory.
- SDOperand Bits = DAG.getNode(ISD::BIT_CONVERT, MVT::i64, Tmp);
+ SDOperand FIPtr = DAG.CreateStackTemporary(MVT::f64);
+
+ // Emit a store to the stack slot.
+ SDOperand Chain = DAG.getStore(DAG.getEntryNode(), Tmp, FIPtr, NULL, 0);
+
+ // Result is a load from the stack slot. If loading 4 bytes, make sure to
+ // add in a bias.
if (Op.getValueType() == MVT::i32)
- Bits = DAG.getNode(ISD::TRUNCATE, MVT::i32, Bits);
- return Bits;
+ FIPtr = DAG.getNode(ISD::ADD, FIPtr.getValueType(), FIPtr,
+ DAG.getConstant(4, FIPtr.getValueType()));
+ return DAG.getLoad(Op.getValueType(), Chain, FIPtr, NULL, 0);
}
static SDOperand LowerFP_ROUND_INREG(SDOperand Op, SelectionDAG &DAG) {
From djg at cray.com Mon Oct 15 15:30:11 2007
From: djg at cray.com (Dan Gohman)
Date: Mon, 15 Oct 2007 20:30:11 -0000
Subject: [llvm-commits] [llvm] r43007 - /llvm/trunk/docs/LangRef.html
Message-ID: <200710152030.l9FKUBxZ012325@zion.cs.uiuc.edu>
Author: djg
Date: Mon Oct 15 15:30:11 2007
New Revision: 43007
URL: http://llvm.org/viewvc/llvm-project?rev=43007&view=rev
Log:
Document the new llvm.sin, llvm.cos, and llvm.pow intrinsics. Feedback
is welcome!
Modified:
llvm/trunk/docs/LangRef.html
Modified: llvm/trunk/docs/LangRef.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=43007&r1=43006&r2=43007&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.html (original)
+++ llvm/trunk/docs/LangRef.html Mon Oct 15 15:30:11 2007
@@ -177,6 +177,9 @@
'llvm.memset.*' Intrinsic
'llvm.sqrt.*' Intrinsic
'llvm.powi.*' Intrinsic
+ 'llvm.sin.*' Intrinsic
+ 'llvm.cos.*' Intrinsic
+ 'llvm.pow.*' Intrinsic
Bit Manipulation Intrinsics
@@ -4492,7 +4495,8 @@
Syntax:
This is an overloaded intrinsic. You can use llvm.sqrt on any
-floating point type. Not all targets support all types however.
+floating point or vector of floating point type. Not all targets support all
+types however.
declare float @llvm.sqrt.f32(float %Val)
declare double @llvm.sqrt.f64(double %Val)
@@ -4505,7 +4509,7 @@
The 'llvm.sqrt' intrinsics return the sqrt of the specified operand,
-returning the same value as the libm 'sqrt' function would. Unlike
+returning the same value as the libm 'sqrt' functions would. Unlike
sqrt in libm, however, llvm.sqrt has undefined behavior for
negative numbers (which allows for better optimization).
@@ -4533,7 +4537,8 @@
Syntax:
This is an overloaded intrinsic. You can use llvm.powi on any
-floating point type. Not all targets support all types however.
+floating point or vector of floating point type. Not all targets support all
+types however.
declare float @llvm.powi.f32(float %Val, i32 %power)
declare double @llvm.powi.f64(double %Val, i32 %power)
@@ -4547,7 +4552,8 @@
The 'llvm.powi.*' intrinsics return the first operand raised to the
specified (positive or negative) power. The order of evaluation of
-multiplications is not defined.
+multiplications is not defined. When a vector of floating point type is
+used, the second argument remains a scalar integer value.
Arguments:
@@ -4564,6 +4570,132 @@
unspecified sequence of rounding operations.
+
+
+
+
+
+
Syntax:
+
This is an overloaded intrinsic. You can use llvm.sin on any
+floating point or vector of floating point type. Not all targets support all
+types however.
+
+ declare float @llvm.sin.f32(float %Val)
+ declare double @llvm.sin.f64(double %Val)
+ declare x86_fp80 @llvm.sin.f80(x86_fp80 %Val)
+ declare fp128 @llvm.sin.f128(fp128 %Val)
+ declare ppc_fp128 @llvm.sin.ppcf128(ppc_fp128 %Val)
+
+
+
Overview:
+
+
+The 'llvm.sin.*' intrinsics return the sine of the operand.
+
+
+
Arguments:
+
+
+The argument and return value are floating point numbers of the same type.
+
+
+
Semantics:
+
+
+This function returns the sine of the specified operand, returning the
+same values as the libm sin functions would, and handles error
+conditions in the same way, unless the --enable-unsafe-fp-math is enabled
+during code generation, in which case the result may have different
+precision and if any errors occur the behavior is undefined.
+
+
+
+
+
+
+
+
Syntax:
+
This is an overloaded intrinsic. You can use llvm.cos on any
+floating point or vector of floating point type. Not all targets support all
+types however.
+
+ declare float @llvm.cos.f32(float %Val)
+ declare double @llvm.cos.f64(double %Val)
+ declare x86_fp80 @llvm.cos.f80(x86_fp80 %Val)
+ declare fp128 @llvm.cos.f128(fp128 %Val)
+ declare ppc_fp128 @llvm.cos.ppcf128(ppc_fp128 %Val)
+
+
+
Overview:
+
+
+The 'llvm.cos.*' intrinsics return the cosine of the operand.
+
+
+
Arguments:
+
+
+The argument and return value are floating point numbers of the same type.
+
+
+
Semantics:
+
+
+This function returns the cosine of the specified operand, returning the
+same values as the libm cos functions would, and handles error
+conditions in the same way, unless the --enable-unsafe-fp-math is enabled
+during code generation, in which case the result may have different
+precision and if any errors occur the behavior is undefined.
+
+
+
+
+
+
+
+
Syntax:
+
This is an overloaded intrinsic. You can use llvm.pow on any
+floating point or vector of floating point type. Not all targets support all
+types however.
+
+ declare float @llvm.pow.f32(float %Val, float %Power)
+ declare double @llvm.pow.f64(double %Val, double %Power)
+ declare x86_fp80 @llvm.pow.f80(x86_fp80 %Val, x86_fp80 %Power)
+ declare fp128 @llvm.pow.f128(fp128 %Val, fp128 %Power)
+ declare ppc_fp128 @llvm.pow.ppcf128(ppc_fp128 %Val, ppc_fp128 Power)
+
+
+
Overview:
+
+
+The 'llvm.pow.*' intrinsics return the first operand raised to the
+specified (positive or negative) power.
+
+
+
Arguments:
+
+
+The second argument is a floating point power, and the first is a value to
+raise to that power.
+
+
+
Semantics:
+
+
+This function returns the first value raised to the second power,
+returning the
+same values as the libm pow functions would, and handles error
+conditions in the same way, unless the --enable-unsafe-fp-math is enabled
+during code generation, in which case the result may have different
+precision and if any errors occur the behavior is undefined.
+
+
From dalej at apple.com Mon Oct 15 15:35:08 2007
From: dalej at apple.com (Dale Johannesen)
Date: Mon, 15 Oct 2007 20:35:08 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r43008 -
/llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c
Message-ID: <200710152035.l9FKZ8pw012480@zion.cs.uiuc.edu>
Author: johannes
Date: Mon Oct 15 15:35:07 2007
New Revision: 43008
URL: http://llvm.org/viewvc/llvm-project?rev=43008&view=rev
Log:
Make previous patch actually work.
Modified:
llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c
Modified: llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c?rev=43008&r1=43007&r2=43008&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c (original)
+++ llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c Mon Oct 15 15:35:07 2007
@@ -9091,26 +9091,6 @@
bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
- /* APPLE LOCAL begin LLVM */
-#ifdef ENABLE_LLVM
- /* LLVM doesn't initialize the RTL backend, so build_vector_type will assign
- all of these types BLKmode. This interferes with rs6000.c-specific
- handling of -faltivec overloads (an apple local patch). As such, give them
- the correct modes here manually. */
- TYPE_MODE (V4SI_type_node) = V4SImode;
- TYPE_MODE (V4SF_type_node) = V4SFmode;
- TYPE_MODE (V8HI_type_node) = V8HImode;
- TYPE_MODE (V16QI_type_node) = V16QImode;
- TYPE_MODE (unsigned_V4SI_type_node) = V4SImode;
- TYPE_MODE (unsigned_V8HI_type_node) = V8HImode;
- TYPE_MODE (unsigned_V16QI_type_node) = V16QImode;
- TYPE_MODE (bool_V16QI_type_node) = V16QImode;
- TYPE_MODE (bool_V8HI_type_node) = V8HImode;
- TYPE_MODE (bool_V4SI_type_node) = V4SImode;
- TYPE_MODE (pixel_V8HI_type_node) = V8HImode;
-#endif
- /* APPLE LOCAL end LLVM */
-
long_integer_type_internal_node = long_integer_type_node;
long_unsigned_type_internal_node = long_unsigned_type_node;
intQI_type_internal_node = intQI_type_node;
@@ -9140,6 +9120,27 @@
bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
+
+ /* APPLE LOCAL begin LLVM */
+#ifdef ENABLE_LLVM
+ /* LLVM doesn't initialize the RTL backend, so build_vector_type will assign
+ all of these types BLKmode. This interferes with rs6000.c-specific
+ handling of -faltivec overloads (an apple local patch). As such, give them
+ the correct modes here manually. */
+ TYPE_MODE (V4SI_type_node) = V4SImode;
+ TYPE_MODE (V4SF_type_node) = V4SFmode;
+ TYPE_MODE (V8HI_type_node) = V8HImode;
+ TYPE_MODE (V16QI_type_node) = V16QImode;
+ TYPE_MODE (unsigned_V4SI_type_node) = V4SImode;
+ TYPE_MODE (unsigned_V8HI_type_node) = V8HImode;
+ TYPE_MODE (unsigned_V16QI_type_node) = V16QImode;
+ TYPE_MODE (bool_V16QI_type_node) = V16QImode;
+ TYPE_MODE (bool_V8HI_type_node) = V8HImode;
+ TYPE_MODE (bool_V4SI_type_node) = V4SImode;
+ TYPE_MODE (pixel_V8HI_type_node) = V8HImode;
+#endif
+ /* APPLE LOCAL end LLVM */
+
(*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
get_identifier ("__vector unsigned char"),
unsigned_V16QI_type_node));
From isanbard at gmail.com Mon Oct 15 15:47:57 2007
From: isanbard at gmail.com (Bill Wendling)
Date: Mon, 15 Oct 2007 20:47:57 -0000
Subject: [llvm-commits] [llvm-gcc-4.0] r43010 -
/llvm-gcc-4.0/trunk/gcc/objc/objc-act.c
Message-ID: <200710152047.l9FKlwqD012936@zion.cs.uiuc.edu>
Author: void
Date: Mon Oct 15 15:47:57 2007
New Revision: 43010
URL: http://llvm.org/viewvc/llvm-project?rev=43010&view=rev
Log:
In new ABI, it wants an 'objc_object' pointer instead of 'objc_protocol_extension' pointer
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=43010&r1=43009&r2=43010&view=diff
==============================================================================
--- llvm-gcc-4.0/trunk/gcc/objc/objc-act.c (original)
+++ llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Mon Oct 15 15:47:57 2007
@@ -9330,15 +9330,8 @@
/* APPLE LOCAL begin radar 4533974 - ObjC newprotocol - radar 4695109 */
/* APPLE LOCAL LLVM - begin NUL pointer */
if (newabi)
- {
- if (!objc_protocol_extension_template)
- build_objc_protocol_extension_template ();
-
- /* 'isa' is NULL in the new ObjC abi */
- expr =
- convert (build_pointer_type (objc_protocol_extension_template),
- build_int_cst (NULL_TREE, 0));
- }
+ /* 'isa' is NULL in the new ObjC abi */
+ expr = convert (objc_object_type, build_int_cst (NULL_TREE, 0));
/* APPLE LOCAL end radar 4533974 - ObjC newprotocol - radar 4695109 */
/* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
/* "isa" field now points to struct _objc_protocol_extension * */
From isanbard at gmail.com Mon Oct 15 15:51:09 2007
From: isanbard at gmail.com (Bill Wendling)
Date: Mon, 15 Oct 2007 20:51:09 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r43011 -
/llvm-gcc-4.2/trunk/gcc/objc/objc-act.c
Message-ID: <200710152051.l9FKpAJR013150@zion.cs.uiuc.edu>
Author: void
Date: Mon Oct 15 15:51:09 2007
New Revision: 43011
URL: http://llvm.org/viewvc/llvm-project?rev=43011&view=rev
Log:
In new ABI, it wants an 'objc_object' pointer instead of 'objc_protocol_extension' pointer
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=43011&r1=43010&r2=43011&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original)
+++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Mon Oct 15 15:51:09 2007
@@ -9230,15 +9230,8 @@
/* APPLE LOCAL begin radar 4533974 - ObjC newprotocol - radar 4695109 */
/* APPLE LOCAL LLVM - begin NUL pointer */
if (newabi)
- {
- if (!objc_protocol_extension_template)
- build_objc_protocol_extension_template ();
-
- /* 'isa' is NULL in the new ObjC abi */
- expr =
- convert (build_pointer_type (objc_protocol_extension_template),
- build_int_cst (NULL_TREE, 0));
- }
+ /* 'isa' is NULL in the new ObjC abi */
+ expr = convert (objc_object_type, build_int_cst (NULL_TREE, 0));
/* APPLE LOCAL end radar 4533974 - ObjC newprotocol - radar 4695109 */
/* APPLE LOCAL begin radar 4585769 - Objective-C 1.0 extensions */
/* "isa" field now points to struct _objc_protocol_extension * */
From dpatel at apple.com Mon Oct 15 15:57:34 2007
From: dpatel at apple.com (Devang Patel)
Date: Mon, 15 Oct 2007 20:57:34 -0000
Subject: [llvm-commits] [llvm-gcc-4.0] r43013 -
/llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp
Message-ID: <200710152057.l9FKvYKM013367@zion.cs.uiuc.edu>
Author: dpatel
Date: Mon Oct 15 15:57:34 2007
New Revision: 43013
URL: http://llvm.org/viewvc/llvm-project?rev=43013&view=rev
Log:
Simplify. Incorporate feedback.
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=43013&r1=43012&r2=43013&view=diff
==============================================================================
--- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Mon Oct 15 15:57:34 2007
@@ -5288,21 +5288,16 @@
// float foo(int w, float A[][w], int g) { return A[g][0]; }
ArrayAddr = BitCastToType(ArrayAddr, PointerType::get(Type::Int8Ty));
- Value *TypeSize = NULL;
- if (VOID_TYPE_P(TREE_TYPE(ArrayType))) {
- // void * size is 1
- Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
- return BitCastToType(Ptr, PointerType::get(Type::Int8Ty));
- }
- else {
- TypeSize = Emit(array_ref_element_size(exp), 0);
- TypeSize = CastToUIntType(TypeSize, IntPtrTy);
- IndexVal = Builder.CreateMul(IndexVal, TypeSize, "tmp");
- Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
- return BitCastToType(Ptr, PointerType::get(ConvertType(TREE_TYPE(exp))));
- }
-
+ if (VOID_TYPE_P(TREE_TYPE(ArrayType)))
+ // void * size is 1
+ return Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
+
+ Value *TypeSize = Emit(array_ref_element_size(exp), 0);
+ TypeSize = CastToUIntType(TypeSize, IntPtrTy);
+ IndexVal = Builder.CreateMul(IndexVal, TypeSize, "tmp");
+ Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
+ return BitCastToType(Ptr, PointerType::get(ConvertType(TREE_TYPE(exp))));
}
/// getFieldOffsetInBits - Return the offset (in bits) of a FIELD_DECL in a
From dpatel at apple.com Mon Oct 15 15:59:02 2007
From: dpatel at apple.com (Devang Patel)
Date: Mon, 15 Oct 2007 20:59:02 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r43014 -
/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
Message-ID: <200710152059.l9FKx2cR013430@zion.cs.uiuc.edu>
Author: dpatel
Date: Mon Oct 15 15:59:02 2007
New Revision: 43014
URL: http://llvm.org/viewvc/llvm-project?rev=43014&view=rev
Log:
Simplify. Incorporate feedback.
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=43014&r1=43013&r2=43014&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Oct 15 15:59:02 2007
@@ -4838,20 +4838,14 @@
// float foo(int w, float A[][w], int g) { return A[g][0]; }
ArrayAddr = BitCastToType(ArrayAddr, PointerType::get(Type::Int8Ty));
- Value *TypeSize = NULL;
- if (VOID_TYPE_P(TREE_TYPE(ArrayType))) {
- Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
- return BitCastToType(Ptr, PointerType::get(Type::Int8Ty));
- }
- else {
- TypeSize = Emit(array_ref_element_size(exp), 0);
- TypeSize = CastToUIntType(TypeSize, IntPtrTy);
- IndexVal = Builder.CreateMul(IndexVal, TypeSize, "tmp");
- Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
- return BitCastToType(Ptr, PointerType::get(ConvertType(TREE_TYPE(exp))));
- }
-
+ if (VOID_TYPE_P(TREE_TYPE(ArrayType)))
+ return Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
+ Value *TypeSize = Emit(array_ref_element_size(exp), 0);
+ TypeSize = CastToUIntType(TypeSize, IntPtrTy);
+ IndexVal = Builder.CreateMul(IndexVal, TypeSize, "tmp");
+ Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal, "tmp");
+ return BitCastToType(Ptr, PointerType::get(ConvertType(TREE_TYPE(exp))));
}
/// getFieldOffsetInBits - Return the offset (in bits) of a FIELD_DECL in a
From djg at cray.com Mon Oct 15 16:07:59 2007
From: djg at cray.com (Dan Gohman)
Date: Mon, 15 Oct 2007 21:07:59 -0000
Subject: [llvm-commits] [llvm] r43015 - /llvm/trunk/docs/CodeGenerator.html
Message-ID: <200710152107.l9FL7xlv014275@zion.cs.uiuc.edu>
Author: djg
Date: Mon Oct 15 16:07:59 2007
New Revision: 43015
URL: http://llvm.org/viewvc/llvm-project?rev=43015&view=rev
Log:
Document the -view-sunit-dags option.
Modified:
llvm/trunk/docs/CodeGenerator.html
Modified: llvm/trunk/docs/CodeGenerator.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodeGenerator.html?rev=43015&r1=43014&r2=43015&view=diff
==============================================================================
--- llvm/trunk/docs/CodeGenerator.html (original)
+++ llvm/trunk/docs/CodeGenerator.html Mon Oct 15 16:07:59 2007
@@ -862,7 +862,11 @@
this, you probably
need to configure
your system to add support for it). The
-view-sched-dags option
views the SelectionDAG output from the Select phase and input to the Scheduler
-phase.
+phase. The
-view-sunit-dags option views the ScheduleDAG, which is
+based on the final SelectionDAG, with nodes that must be scheduled as a unit
+bundled together into a single node, and with immediate operands and other
+nodes that aren't relevent for scheduling omitted.
+
From djg at cray.com Mon Oct 15 16:10:03 2007
From: djg at cray.com (Dan Gohman)
Date: Mon, 15 Oct 2007 21:10:03 -0000
Subject: [llvm-commits] [llvm] r43016 - /llvm/trunk/tools/llvm-ar/llvm-ar.cpp
Message-ID: <200710152110.l9FLA3E5014368@zion.cs.uiuc.edu>
Author: djg
Date: Mon Oct 15 16:10:03 2007
New Revision: 43016
URL: http://llvm.org/viewvc/llvm-project?rev=43016&view=rev
Log:
Fix a typo in a comment.
Modified:
llvm/trunk/tools/llvm-ar/llvm-ar.cpp
Modified: llvm/trunk/tools/llvm-ar/llvm-ar.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-ar/llvm-ar.cpp?rev=43016&r1=43015&r2=43016&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-ar/llvm-ar.cpp (original)
+++ llvm/trunk/tools/llvm-ar/llvm-ar.cpp Mon Oct 15 16:10:03 2007
@@ -23,7 +23,7 @@
#include
using namespace llvm;
-// Option for compatibility with ASIX, not used but must allow it to be present.
+// Option for compatibility with AIX, not used but must allow it to be present.
static cl::opt
X32Option ("X32_64", cl::Hidden,
cl::desc("Ignored option for compatibility with AIX"));
From baldrick at free.fr Mon Oct 15 16:22:34 2007
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 15 Oct 2007 23:22:34 +0200
Subject: [llvm-commits]
=?iso-8859-1?q?=5Bllvm=5D_r42981_-_in_/llvm/trunk?=
=?iso-8859-1?q?=3A_include/llvm/CodeGen/SelectionDAG=2Eh=09lib/CodeGen/Se?=
=?iso-8859-1?q?lectionDAG/DAGCombiner=2Ecpp_lib/CodeGen/SelectionDAG/Lega?=
=?iso-8859-1?q?lizeDAGTypes=2Ecpp_lib/CodeGen/SelectionDAG/ScheduleDAGRRL?=
=?iso-8859-1?q?ist=2Ecpp_lib/CodeGen/SelectionDAG/SelectionDAG=2Ecpp_lib/?=
=?iso-8859-1?q?CodeGen/SelectionDAG/SelectionDAGISel=2Ecpp=09utils/TableG?=
=?iso-8859-1?q?en/DAGISelEmitter=2Ecpp?=
In-Reply-To:
References: <200710150610.l9F6ANV3030436@zion.cs.uiuc.edu>
<200710151401.46887.baldrick@free.fr>
Message-ID: <200710152322.35643.baldrick@free.fr>
Hi Chris,
> > By the way the logic supposes that the result of any node is an
> > operand for
> > some other node. Is at least one result always used?
>
> Nope, nodes are allowed to be unreachable/dead. What part assumes
> that they are used?
I thought I had spotted a problem, but I can't find it anymore,
so don't worry about it :)
Ciao,
Duncan.
From evan.cheng at apple.com Mon Oct 15 16:33:22 2007
From: evan.cheng at apple.com (Evan Cheng)
Date: Mon, 15 Oct 2007 21:33:22 -0000
Subject: [llvm-commits] [llvm] r43017 -
/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp
Message-ID: <200710152133.l9FLXMXG015140@zion.cs.uiuc.edu>
Author: evancheng
Date: Mon Oct 15 16:33:22 2007
New Revision: 43017
URL: http://llvm.org/viewvc/llvm-project?rev=43017&view=rev
Log:
Make CalcLatency() non-recursive.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=43017&r1=43016&r2=43017&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Mon Oct 15 16:33:22 2007
@@ -443,22 +443,57 @@
int &Latency = Latencies[SU.NodeNum];
if (Latency != -1)
return Latency;
-
- int MaxSuccLatency = 0;
- for (SUnit::const_succ_iterator I = SU.Succs.begin(), E = SU.Succs.end();
- I != E; ++I)
- MaxSuccLatency = std::max(MaxSuccLatency, CalcLatency(*I->Dep));
- return Latency = MaxSuccLatency + SU.Latency;
+ std::vector WorkList;
+ WorkList.push_back(&SU);
+ while (!WorkList.empty()) {
+ const SUnit *Cur = WorkList.back();
+ bool AllDone = true;
+ int MaxSuccLatency = 0;
+ for (SUnit::const_succ_iterator I = Cur->Succs.begin(),E = Cur->Succs.end();
+ I != E; ++I) {
+ int SuccLatency = Latencies[I->Dep->NodeNum];
+ if (SuccLatency == -1) {
+ AllDone = false;
+ WorkList.push_back(I->Dep);
+ } else {
+ MaxSuccLatency = std::max(MaxSuccLatency, SuccLatency);
+ }
+ }
+ if (AllDone) {
+ Latencies[Cur->NodeNum] = MaxSuccLatency + Cur->Latency;
+ WorkList.pop_back();
+ }
+ }
+
+ return Latency;
}
/// CalculatePriorities - Calculate priorities of all scheduling units.
void LatencyPriorityQueue::CalculatePriorities() {
Latencies.assign(SUnits->size(), -1);
NumNodesSolelyBlocking.assign(SUnits->size(), 0);
-
- for (unsigned i = 0, e = SUnits->size(); i != e; ++i)
- CalcLatency((*SUnits)[i]);
+
+ // For each node, calculate the maximal path from the node to the exit.
+ std::vector > WorkList;
+ for (unsigned i = 0, e = SUnits->size(); i != e; ++i) {
+ const SUnit *SU = &(*SUnits)[i];
+ if (SU->Succs.size() == 0)
+ WorkList.push_back(std::make_pair(SU, 0U));
+ }
+
+ while (!WorkList.empty()) {
+ const SUnit *SU = WorkList.back().first;
+ unsigned SuccLat = WorkList.back().second;
+ WorkList.pop_back();
+ int &Latency = Latencies[SU->NodeNum];
+ if (Latency == -1 || (SU->Latency + SuccLat) > (unsigned)Latency) {
+ Latency = SU->Latency + SuccLat;
+ for (SUnit::const_pred_iterator I = SU->Preds.begin(),E = SU->Preds.end();
+ I != E; ++I)
+ WorkList.push_back(std::make_pair(I->Dep, Latency));
+ }
+ }
}
/// getSingleUnscheduledPred - If there is exactly one unscheduled predecessor
From dpatel at apple.com Mon Oct 15 16:59:23 2007
From: dpatel at apple.com (Devang Patel)
Date: Mon, 15 Oct 2007 21:59:23 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r43018 - in /llvm-gcc-4.2/trunk:
gcc/Makefile.in gcc/configure gcc/configure.ac libcpp/configure
libcpp/configure.ac
Message-ID: <200710152159.l9FLxNim016022@zion.cs.uiuc.edu>
Author: dpatel
Date: Mon Oct 15 16:59:22 2007
New Revision: 43018
URL: http://llvm.org/viewvc/llvm-project?rev=43018&view=rev
Log:
Accept installed llvm location (e.g. allow --enable-llvm=/usr/local )
Modified:
llvm-gcc-4.2/trunk/gcc/Makefile.in
llvm-gcc-4.2/trunk/gcc/configure
llvm-gcc-4.2/trunk/gcc/configure.ac
llvm-gcc-4.2/trunk/libcpp/configure
llvm-gcc-4.2/trunk/libcpp/configure.ac
Modified: llvm-gcc-4.2/trunk/gcc/Makefile.in
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/Makefile.in?rev=43018&r1=43017&r2=43018&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/Makefile.in (original)
+++ llvm-gcc-4.2/trunk/gcc/Makefile.in Mon Oct 15 16:59:22 2007
@@ -234,7 +234,11 @@
# Determine BUILDMODE from configure run (--enable-llvm)
BUILDMODE := @LLVMBUILDMODE@
+ifneq ($(BUILDMODE),)
LLVMBINPATH = $(LLVMOBJDIR)/$(BUILDMODE)/bin
+else
+LLVMBINPATH = $(LLVMOBJDIR)/bin
+endif
ifeq ($(LLVMOBJDIR),)
CPPFLAGS = @CPPFLAGS@
Modified: llvm-gcc-4.2/trunk/gcc/configure
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/configure?rev=43018&r1=43017&r2=43018&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/configure (original)
+++ llvm-gcc-4.2/trunk/gcc/configure Mon Oct 15 16:59:22 2007
@@ -7392,6 +7392,8 @@
elif test -x "$LLVMBASEPATH/Debug-Asserts+Checks/bin/llc$EXEEXT"; then
echo Found Debug-Asserts+Checks LLVM Tree in $LLVMBASEPATH
LLVMBUILDMODE="Debug-Asserts+Checks"
+ elif test -x "$LLVMBASEPATH/bin/llc$EXEEXT"; then
+ echo Found Installed LLVM Tree in $LLVMBASEPATH
else
{ { echo "$as_me:$LINENO: error: You must specify valid path to your LLVM tree with --enable-llvm=DIR" >&5
echo "$as_me: error: You must specify valid path to your LLVM tree with --enable-llvm=DIR" >&2;}
@@ -8018,7 +8020,7 @@
else
ac_prog_version=`$MAKEINFO --version 2>&1 |
sed -n 's/^.*GNU texinfo.* \([0-9][0-9.]*\).*$/\1/p'`
- echo "configure:8021: version of makeinfo is $ac_prog_version" >&5
+ echo "configure:8023: version of makeinfo is $ac_prog_version" >&5
case $ac_prog_version in
'') gcc_cv_prog_makeinfo_modern=no;;
4.[4-9]*)
Modified: llvm-gcc-4.2/trunk/gcc/configure.ac
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/configure.ac?rev=43018&r1=43017&r2=43018&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/configure.ac (original)
+++ llvm-gcc-4.2/trunk/gcc/configure.ac Mon Oct 15 16:59:22 2007
@@ -877,6 +877,8 @@
elif test -x "$LLVMBASEPATH/Debug-Asserts+Checks/bin/llc$EXEEXT"; then
echo Found Debug-Asserts+Checks LLVM Tree in $LLVMBASEPATH
LLVMBUILDMODE="Debug-Asserts+Checks"
+ elif test -x "$LLVMBASEPATH/bin/llc$EXEEXT"; then
+ echo Found Installed LLVM Tree in $LLVMBASEPATH
else
AC_MSG_ERROR([You must specify valid path to your LLVM tree with --enable-llvm=DIR])
fi
Modified: llvm-gcc-4.2/trunk/libcpp/configure
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libcpp/configure?rev=43018&r1=43017&r2=43018&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/libcpp/configure (original)
+++ llvm-gcc-4.2/trunk/libcpp/configure Mon Oct 15 16:59:22 2007
@@ -8310,6 +8310,8 @@
elif test -x "$LLVMBASEPATH/Debug-Asserts+Checks/bin/llc$EXEEXT"; then
echo Found Debug-Asserts+Checks LLVM Tree in $LLVMBASEPATH
LLVMBUILDMODE="Debug-Asserts+Checks"
+ elif test -x "$LLVMBASEPATH/bin/llc$EXEEXT"; then
+ echo Found Installed LLVM Tree in $LLVMBASEPATH
else
{ { echo "$as_me:$LINENO: error: You must specify valid path to your LLVM tree with --enable-llvm=DIR" >&5
echo "$as_me: error: You must specify valid path to your LLVM tree with --enable-llvm=DIR" >&2;}
Modified: llvm-gcc-4.2/trunk/libcpp/configure.ac
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libcpp/configure.ac?rev=43018&r1=43017&r2=43018&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/libcpp/configure.ac (original)
+++ llvm-gcc-4.2/trunk/libcpp/configure.ac Mon Oct 15 16:59:22 2007
@@ -186,6 +186,8 @@
elif test -x "$LLVMBASEPATH/Debug-Asserts+Checks/bin/llc$EXEEXT"; then
echo Found Debug-Asserts+Checks LLVM Tree in $LLVMBASEPATH
LLVMBUILDMODE="Debug-Asserts+Checks"
+ elif test -x "$LLVMBASEPATH/bin/llc$EXEEXT"; then
+ echo Found Installed LLVM Tree in $LLVMBASEPATH
else
AC_MSG_ERROR([You must specify valid path to your LLVM tree with --enable-llvm=DIR])
fi
From dpatel at apple.com Mon Oct 15 17:01:15 2007
From: dpatel at apple.com (Devang Patel)
Date: Mon, 15 Oct 2007 22:01:15 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r43019 -
/llvm-gcc-4.2/trunk/gcc/passes.c
Message-ID: <200710152201.l9FM1FfP016103@zion.cs.uiuc.edu>
Author: dpatel
Date: Mon Oct 15 17:01:14 2007
New Revision: 43019
URL: http://llvm.org/viewvc/llvm-project?rev=43019&view=rev
Log:
dead strip rtl passes.
Modified:
llvm-gcc-4.2/trunk/gcc/passes.c
Modified: llvm-gcc-4.2/trunk/gcc/passes.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/passes.c?rev=43019&r1=43018&r2=43019&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/passes.c (original)
+++ llvm-gcc-4.2/trunk/gcc/passes.c Mon Oct 15 17:01:14 2007
@@ -659,6 +659,8 @@
NEXT_PASS (pass_dce_loop);
*p = NULL;
+ /* LLVM LOCAL begin */
+#ifndef ENABLE_LLVM
p = &pass_loop2.sub;
NEXT_PASS (pass_rtl_loop_init);
NEXT_PASS (pass_rtl_move_loop_invariants);
@@ -733,6 +735,8 @@
NEXT_PASS (pass_set_nothrow_function_flags);
NEXT_PASS (pass_final);
*p = NULL;
+#endif
+ /* LLVM LOCAL end */
#undef NEXT_PASS
From djg at cray.com Mon Oct 15 17:07:31 2007
From: djg at cray.com (Dan Gohman)
Date: Mon, 15 Oct 2007 22:07:31 -0000
Subject: [llvm-commits] [llvm] r43020 -
/llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp
Message-ID: <200710152207.l9FM7Vrh016322@zion.cs.uiuc.edu>
Author: djg
Date: Mon Oct 15 17:07:31 2007
New Revision: 43020
URL: http://llvm.org/viewvc/llvm-project?rev=43020&view=rev
Log:
Teach IntrinsicLowering.cpp about the sin, cos, and pow intrinsics.
Modified:
llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp
Modified: llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp?rev=43020&r1=43019&r2=43020&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp Mon Oct 15 17:07:31 2007
@@ -114,6 +114,51 @@
I->arg_begin()->getType());
}
break;
+ case Intrinsic::sin:
+ switch((int)I->arg_begin()->getType()->getTypeID()) {
+ case Type::FloatTyID:
+ EnsureFunctionExists(M, "sinf", I->arg_begin(), I->arg_end(),
+ Type::FloatTy);
+ case Type::DoubleTyID:
+ EnsureFunctionExists(M, "sin", I->arg_begin(), I->arg_end(),
+ Type::DoubleTy);
+ case Type::X86_FP80TyID:
+ case Type::FP128TyID:
+ case Type::PPC_FP128TyID:
+ EnsureFunctionExists(M, "sinl", I->arg_begin(), I->arg_end(),
+ I->arg_begin()->getType());
+ }
+ break;
+ case Intrinsic::cos:
+ switch((int)I->arg_begin()->getType()->getTypeID()) {
+ case Type::FloatTyID:
+ EnsureFunctionExists(M, "cosf", I->arg_begin(), I->arg_end(),
+ Type::FloatTy);
+ case Type::DoubleTyID:
+ EnsureFunctionExists(M, "cos", I->arg_begin(), I->arg_end(),
+ Type::DoubleTy);
+ case Type::X86_FP80TyID:
+ case Type::FP128TyID:
+ case Type::PPC_FP128TyID:
+ EnsureFunctionExists(M, "cosl", I->arg_begin(), I->arg_end(),
+ I->arg_begin()->getType());
+ }
+ break;
+ case Intrinsic::pow:
+ switch((int)I->arg_begin()->getType()->getTypeID()) {
+ case Type::FloatTyID:
+ EnsureFunctionExists(M, "powf", I->arg_begin(), I->arg_end(),
+ Type::FloatTy);
+ case Type::DoubleTyID:
+ EnsureFunctionExists(M, "pow", I->arg_begin(), I->arg_end(),
+ Type::DoubleTy);
+ case Type::X86_FP80TyID:
+ case Type::FP128TyID:
+ case Type::PPC_FP128TyID:
+ EnsureFunctionExists(M, "powl", I->arg_begin(), I->arg_end(),
+ I->arg_begin()->getType());
+ }
+ break;
}
}
From sabre at nondot.org Mon Oct 15 22:00:22 2007
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 16 Oct 2007 03:00:22 -0000
Subject: [llvm-commits] [llvm] r43025 -
/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
Message-ID: <200710160300.l9G30MMp026561@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Oct 15 22:00:22 2007
New Revision: 43025
URL: http://llvm.org/viewvc/llvm-project?rev=43025&view=rev
Log:
implement promotion of select and select_cc, allowing MallocBench/gs to
work with type promotion on x86.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=43025&r1=43024&r2=43025&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Mon Oct 15 22:00:22 2007
@@ -130,6 +130,8 @@
SDOperand PromoteResult_SETCC(SDNode *N);
SDOperand PromoteResult_LOAD(LoadSDNode *N);
SDOperand PromoteResult_SimpleIntBinOp(SDNode *N);
+ SDOperand PromoteResult_SELECT (SDNode *N);
+ SDOperand PromoteResult_SELECT_CC(SDNode *N);
// Result Expansion.
void ExpandResult(SDNode *N, unsigned ResNo);
@@ -450,6 +452,10 @@
case ISD::ADD:
case ISD::SUB:
case ISD::MUL: Result = PromoteResult_SimpleIntBinOp(N); break;
+
+ case ISD::SELECT: Result = PromoteResult_SELECT(N); break;
+ case ISD::SELECT_CC: Result = PromoteResult_SELECT_CC(N); break;
+
}
// If Result is null, the sub-method took care of registering the result.
@@ -552,6 +558,19 @@
return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
}
+SDOperand DAGTypeLegalizer::PromoteResult_SELECT(SDNode *N) {
+ SDOperand LHS = GetPromotedOp(N->getOperand(1));
+ SDOperand RHS = GetPromotedOp(N->getOperand(2));
+ return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS);
+}
+
+SDOperand DAGTypeLegalizer::PromoteResult_SELECT_CC(SDNode *N) {
+ SDOperand LHS = GetPromotedOp(N->getOperand(2));
+ SDOperand RHS = GetPromotedOp(N->getOperand(3));
+ return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0),
+ N->getOperand(1), LHS, RHS, N->getOperand(4));
+}
+
//===----------------------------------------------------------------------===//
// Result Expansion
//===----------------------------------------------------------------------===//
From evan.cheng at apple.com Tue Oct 16 03:04:24 2007
From: evan.cheng at apple.com (Evan Cheng)
Date: Tue, 16 Oct 2007 08:04:24 -0000
Subject: [llvm-commits] [llvm] r43026 - in /llvm/trunk:
include/llvm/CodeGen/SimpleRegisterCoalescing.h
lib/CodeGen/SimpleRegisterCoalescing.cpp
Message-ID: <200710160804.l9G84P8p014119@zion.cs.uiuc.edu>
Author: evancheng
Date: Tue Oct 16 03:04:24 2007
New Revision: 43026
URL: http://llvm.org/viewvc/llvm-project?rev=43026&view=rev
Log:
Code clean up.
Modified:
llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h
llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
Modified: llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h?rev=43026&r1=43025&r2=43026&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h Tue Oct 16 03:04:24 2007
@@ -100,7 +100,7 @@
/// CopyCoalesceInMBB - Coalesce copies in the specified MBB, putting
/// copies that cannot yet be coalesced into the "TryAgain" list.
void CopyCoalesceInMBB(MachineBasicBlock *MBB,
- std::vector *TryAgain, bool PhysOnly = false);
+ std::vector &TryAgain);
/// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg,
/// which are the src/dst of the copy instruction CopyMI. This returns true
@@ -108,8 +108,7 @@
/// to coalesce these this copy, due to register constraints. It returns
/// false if it is not currently possible to coalesce this interval, but
/// it may be possible if other things get coalesced.
- bool JoinCopy(MachineInstr *CopyMI, unsigned SrcReg, unsigned DstReg,
- bool PhysOnly = false);
+ bool JoinCopy(MachineInstr *CopyMI, unsigned SrcReg, unsigned DstReg);
/// JoinIntervals - Attempt to join these two intervals. On failure, this
/// returns false. Otherwise, if one of the intervals being joined is a
Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=43026&r1=43025&r2=43026&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Tue Oct 16 03:04:24 2007
@@ -192,7 +192,7 @@
/// false if it is not currently possible to coalesce this interval, but
/// it may be possible if other things get coalesced.
bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI,
- unsigned SrcReg, unsigned DstReg, bool PhysOnly) {
+ unsigned SrcReg, unsigned DstReg) {
DOUT << li_->getInstructionIndex(CopyMI) << '\t' << *CopyMI;
// Get representative registers.
@@ -207,9 +207,6 @@
bool SrcIsPhys = MRegisterInfo::isPhysicalRegister(repSrcReg);
bool DstIsPhys = MRegisterInfo::isPhysicalRegister(repDstReg);
- if (PhysOnly && !SrcIsPhys && !DstIsPhys)
- // Only joining physical registers with virtual registers in this round.
- return true;
// If they are both physical registers, we cannot join them.
if (SrcIsPhys && DstIsPhys) {
@@ -932,9 +929,11 @@
}
void SimpleRegisterCoalescing::CopyCoalesceInMBB(MachineBasicBlock *MBB,
- std::vector *TryAgain, bool PhysOnly) {
+ std::vector &TryAgain) {
DOUT << ((Value*)MBB->getBasicBlock())->getName() << ":\n";
+ std::vector VirtCopies;
+ std::vector PhysCopies;
for (MachineBasicBlock::iterator MII = MBB->begin(), E = MBB->end();
MII != E;) {
MachineInstr *Inst = MII++;
@@ -946,10 +945,27 @@
SrcReg = Inst->getOperand(1).getReg();
} else if (!tii_->isMoveInstr(*Inst, SrcReg, DstReg))
continue;
-
- bool Done = JoinCopy(Inst, SrcReg, DstReg, PhysOnly);
- if (TryAgain && !Done)
- TryAgain->push_back(getCopyRec(Inst, SrcReg, DstReg));
+
+ unsigned repSrcReg = rep(SrcReg);
+ unsigned repDstReg = rep(DstReg);
+ bool SrcIsPhys = MRegisterInfo::isPhysicalRegister(repSrcReg);
+ bool DstIsPhys = MRegisterInfo::isPhysicalRegister(repDstReg);
+ if (SrcIsPhys || DstIsPhys)
+ PhysCopies.push_back(getCopyRec(Inst, SrcReg, DstReg));
+ else
+ VirtCopies.push_back(getCopyRec(Inst, SrcReg, DstReg));
+ }
+
+ // Try coalescing physical register + virtual register first.
+ for (unsigned i = 0, e = PhysCopies.size(); i != e; ++i) {
+ CopyRec &TheCopy = PhysCopies[i];
+ if (!JoinCopy(TheCopy.MI, TheCopy.SrcReg, TheCopy.DstReg))
+ TryAgain.push_back(TheCopy);
+ }
+ for (unsigned i = 0, e = VirtCopies.size(); i != e; ++i) {
+ CopyRec &TheCopy = VirtCopies[i];
+ if (!JoinCopy(TheCopy.MI, TheCopy.SrcReg, TheCopy.DstReg))
+ TryAgain.push_back(TheCopy);
}
}
@@ -965,7 +981,7 @@
// If there are no loops in the function, join intervals in function order.
for (MachineFunction::iterator I = mf_->begin(), E = mf_->end();
I != E; ++I)
- CopyCoalesceInMBB(I, &TryAgainList);
+ CopyCoalesceInMBB(I, TryAgainList);
} else {
// Otherwise, join intervals in inner loops before other intervals.
// Unfortunately we can't just iterate over loop hierarchy here because
@@ -982,9 +998,7 @@
// Finally, join intervals in loop nest order.
for (unsigned i = 0, e = MBBs.size(); i != e; ++i)
- CopyCoalesceInMBB(MBBs[i].second, NULL, true);
- for (unsigned i = 0, e = MBBs.size(); i != e; ++i)
- CopyCoalesceInMBB(MBBs[i].second, &TryAgainList, false);
+ CopyCoalesceInMBB(MBBs[i].second, TryAgainList);
}
// Joining intervals can allow other intervals to be joined. Iteratively join
From arnold.schwaighofer at gmail.com Tue Oct 16 04:05:01 2007
From: arnold.schwaighofer at gmail.com (Arnold Schwaighofer)
Date: Tue, 16 Oct 2007 09:05:01 -0000
Subject: [llvm-commits] [llvm] r43027 -
/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
Message-ID: <200710160905.l9G951hR017802@zion.cs.uiuc.edu>
Author: arnolds
Date: Tue Oct 16 04:05:00 2007
New Revision: 43027
URL: http://llvm.org/viewvc/llvm-project?rev=43027&view=rev
Log:
Correction to tail call optimization code. The new return address
was stored to the acutal stack slot before the parameters were
lowered to their stack slot. This could cause arguments to be
overwritten by the return address if the called function had less
parameters than the caller function. The update should remove the
last failing test case of llc-beta: SPASS.
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=43027&r1=43026&r2=43027&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Oct 16 04:05:00 2007
@@ -707,10 +707,11 @@
Operands.push_back(StackAdjustment);
// Copy registers used by the call. Last operand is a flag so it is not
// copied.
- for(unsigned i=3; i < TailCall.getNumOperands()-1;i++) {
+ for (unsigned i=3; i < TailCall.getNumOperands()-1; i++) {
Operands.push_back(Chain.getOperand(i));
}
- return DAG.getNode(X86ISD::TC_RETURN, MVT::Other, &Operands[0], Operands.size());
+ return DAG.getNode(X86ISD::TC_RETURN, MVT::Other, &Operands[0],
+ Operands.size());
}
// Regular return.
@@ -1520,23 +1521,25 @@
if (FPDiff < (MF.getInfo()->getTCReturnAddrDelta()))
MF.getInfo()->setTCReturnAddrDelta(FPDiff);
- // Adjust the ret address stack slot.
+ Chain = DAG.
+ getCALLSEQ_START(Chain, DAG.getConstant(NumBytesToBePushed, getPointerTy()));
+
+ // Adjust the Return address stack slot.
+ SDOperand RetAddrFrIdx, NewRetAddrFrIdx;
if (FPDiff) {
MVT::ValueType VT = is64Bit ? MVT::i64 : MVT::i32;
- SDOperand RetAddrFrIdx = getReturnAddressFrameIndex(DAG);
+ RetAddrFrIdx = getReturnAddressFrameIndex(DAG);
+ // Load the "old" Return address.
RetAddrFrIdx =
- DAG.getLoad(VT, DAG.getEntryNode(),RetAddrFrIdx, NULL, 0);
- // Emit a store of the saved ret value to the new location.
+ DAG.getLoad(VT, Chain,RetAddrFrIdx, NULL, 0);
+ // Calculate the new stack slot for the return address.
int SlotSize = is64Bit ? 8 : 4;
int NewReturnAddrFI =
MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-SlotSize);
- SDOperand NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, VT);
- Chain = DAG.getStore(Chain,RetAddrFrIdx, NewRetAddrFrIdx, NULL, 0);
+ NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, VT);
+ Chain = SDOperand(RetAddrFrIdx.Val, 1);
}
- Chain = DAG.
- getCALLSEQ_START(Chain, DAG.getConstant(NumBytesToBePushed, getPointerTy()));
-
SmallVector, 8> RegsToPass;
SmallVector MemOpChains;
SmallVector MemOpChains2;
@@ -1592,6 +1595,7 @@
InFlag = Chain.getValue(1);
}
InFlag = SDOperand();
+
// Copy from stack slots to stack slot of a tail called function. This needs
// to be done because if we would lower the arguments directly to their real
// stack slot we might end up overwriting each other.
@@ -1637,6 +1641,10 @@
Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
&MemOpChains2[0], MemOpChains.size());
+ // Store the return address to the appropriate stack slot.
+ if (FPDiff)
+ Chain = DAG.getStore(Chain,RetAddrFrIdx, NewRetAddrFrIdx, NULL, 0);
+
// ELF / PIC requires GOT in the EBX register before function calls via PLT
// GOT pointer.
// Does not work with tail call since ebx is not restored correctly by
From baldrick at free.fr Tue Oct 16 04:07:22 2007
From: baldrick at free.fr (Duncan Sands)
Date: Tue, 16 Oct 2007 09:07:22 -0000
Subject: [llvm-commits] [llvm] r43028 -
/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Message-ID: <200710160907.l9G97M6G018043@zion.cs.uiuc.edu>
Author: baldrick
Date: Tue Oct 16 04:07:20 2007
New Revision: 43028
URL: http://llvm.org/viewvc/llvm-project?rev=43028&view=rev
Log:
Fixes due to lack of type-safety for ValueType: (1) ValueType
being passed instead of an opcode; (2) ValueType being passed
for isVolatile (!) in getLoad.
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=43028&r1=43027&r2=43028&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Oct 16 04:07:20 2007
@@ -772,7 +772,7 @@
case ISD::STRING:
case ISD::CONDCODE:
// Primitives must all be legal.
- assert(TLI.isOperationLegal(Node->getValueType(0), Node->getValueType(0)) &&
+ assert(TLI.isOperationLegal(Node->getOpcode(), Node->getValueType(0)) &&
"This must be legal!");
break;
default:
@@ -2752,7 +2752,7 @@
case ISD::UDIVREM:
// These nodes will only be produced by target-specific lowering, so
// they shouldn't be here if they aren't legal.
- assert(TLI.isOperationLegal(Node->getValueType(0), Node->getValueType(0)) &&
+ assert(TLI.isOperationLegal(Node->getOpcode(), Node->getValueType(0)) &&
"This must be legal!");
Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
@@ -3521,7 +3521,7 @@
} else {
Result = DAG.getTruncStore(DAG.getEntryNode(), Node->getOperand(0),
StackSlot, NULL, 0, newVT);
- Result = DAG.getLoad(newVT, Result, StackSlot, NULL, 0, newVT);
+ Result = DAG.getLoad(newVT, Result, StackSlot, NULL, 0);
}
break;
}
From baldrick at free.fr Tue Oct 16 04:56:50 2007
From: baldrick at free.fr (Duncan Sands)
Date: Tue, 16 Oct 2007 09:56:50 -0000
Subject: [llvm-commits] [llvm] r43030 - in /llvm/trunk:
include/llvm/CodeGen/ValueTypes.h include/llvm/Target/TargetLowering.h
lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/VMCore/ValueTypes.cpp
Message-ID: <200710160956.l9G9uoRa020224@zion.cs.uiuc.edu>
Author: baldrick
Date: Tue Oct 16 04:56:48 2007
New Revision: 43030
URL: http://llvm.org/viewvc/llvm-project?rev=43030&view=rev
Log:
Initial infrastructure for arbitrary precision integer
codegen support. This should have no effect on codegen
for other types. Debatable bits: (1) the use (abuse?)
of a set in SDNode::getValueTypeList; (2) the length of
getTypeToTransformTo, which maybe should be refactored
with a non-inline part for extended value types.
Modified:
llvm/trunk/include/llvm/CodeGen/ValueTypes.h
llvm/trunk/include/llvm/Target/TargetLowering.h
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/trunk/lib/VMCore/ValueTypes.cpp
Modified: llvm/trunk/include/llvm/CodeGen/ValueTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ValueTypes.h?rev=43030&r1=43029&r2=43030&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ValueTypes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ValueTypes.h Tue Oct 16 04:56:48 2007
@@ -19,6 +19,7 @@
#include
#include
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
namespace llvm {
class Type;
@@ -38,6 +39,9 @@
i64 = 5, // This is a 64 bit integer value
i128 = 6, // This is a 128 bit integer value
+ FIRST_INTEGER_VALUETYPE = i1,
+ LAST_INTEGER_VALUETYPE = i128,
+
f32 = 7, // This is a 32 bit floating point value
f64 = 8, // This is a 64 bit floating point value
f80 = 9, // This is a 80 bit floating point value
@@ -46,22 +50,22 @@
Flag = 12, // This is a condition code or machine flag.
isVoid = 13, // This has no value
-
+
v8i8 = 14, // 8 x i8
v4i16 = 15, // 4 x i16
v2i32 = 16, // 2 x i32
v1i64 = 17, // 1 x i64
v16i8 = 18, // 16 x i8
v8i16 = 19, // 8 x i16
- v3i32 = 20, // 3 x i32
+ v3i32 = 20, // 3 x i32
v4i32 = 21, // 4 x i32
v2i64 = 22, // 2 x i64
v2f32 = 23, // 2 x f32
- v3f32 = 24, // 3 x f32
+ v3f32 = 24, // 3 x f32
v4f32 = 25, // 4 x f32
v2f64 = 26, // 2 x f64
-
+
FIRST_VECTOR_VALUETYPE = v8i8,
LAST_VECTOR_VALUETYPE = v2f64,
@@ -70,12 +74,12 @@
// fAny - Any floating-point or vector floating-point value. This is used
// for intrinsics that have overloadings based on floating-point types.
// This is only for tblgen's consumption!
- fAny = 253,
+ fAny = 253,
// iAny - An integer or vector integer value of any bit width. This is
// used for intrinsics that have overloadings based on integer bit widths.
// This is only for tblgen's consumption!
- iAny = 254,
+ iAny = 254,
// iPTR - An int value the size of the pointer of the current
// target. This should only be used internal to tblgen!
@@ -93,17 +97,36 @@
/// value types that are not legal.
///
/// @internal
- /// Currently extended types are always vector types. Extended types are
- /// encoded by having the first SimpleTypeBits bits encode the vector
- /// element type (which must be a scalar type) and the remaining upper
- /// bits encode the vector length, offset by one.
+ /// Extended types are either vector types or arbitrary precision integers.
+ /// Arbitrary precision integers have iAny in the first SimpleTypeBits bits,
+ /// and the bit-width in the next PrecisionBits bits, offset by minus one.
+ /// Vector types are encoded by having the first SimpleTypeBits+PrecisionBits
+ /// bits encode the vector element type (which must be a scalar type, possibly
+ /// an arbitrary precision integer) and the remaining VectorBits upper bits
+ /// encode the vector length, offset by one.
+ ///
+ /// 31--------------16-----------8-------------0
+ /// | Vector length | Precision | Simple type |
+ /// | Vector element |
+
typedef uint32_t ValueType;
static const int SimpleTypeBits = 8;
+ static const int PrecisionBits = 8;
+ static const int VectorBits = 32 - SimpleTypeBits - PrecisionBits;
static const uint32_t SimpleTypeMask =
(~uint32_t(0) << (32 - SimpleTypeBits)) >> (32 - SimpleTypeBits);
+ static const uint32_t PrecisionMask =
+ ((~uint32_t(0) << VectorBits) >> (32 - PrecisionBits)) << SimpleTypeBits;
+
+ static const uint32_t VectorMask =
+ (~uint32_t(0) >> (32 - VectorBits)) << (32 - VectorBits);
+
+ static const uint32_t ElementMask =
+ (~uint32_t(0) << VectorBits) >> VectorBits;
+
/// MVT::isExtendedVT - Test if the given ValueType is extended
/// (as opposed to being simple).
static inline bool isExtendedVT(ValueType VT) {
@@ -114,33 +137,34 @@
/// type.
static inline bool isInteger(ValueType VT) {
ValueType SVT = VT & SimpleTypeMask;
- return (SVT >= i1 && SVT <= i128) || (SVT >= v8i8 && SVT <= v2i64);
+ return (SVT >= FIRST_INTEGER_VALUETYPE && SVT <= LAST_INTEGER_VALUETYPE) ||
+ (SVT >= v8i8 && SVT <= v2i64) || (SVT == iAny && (VT & PrecisionMask));
}
-
+
/// MVT::isFloatingPoint - Return true if this is an FP, or a vector FP type.
static inline bool isFloatingPoint(ValueType VT) {
ValueType SVT = VT & SimpleTypeMask;
return (SVT >= f32 && SVT <= ppcf128) || (SVT >= v2f32 && SVT <= v2f64);
}
-
+
/// MVT::isVector - Return true if this is a vector value type.
static inline bool isVector(ValueType VT) {
return (VT >= FIRST_VECTOR_VALUETYPE && VT <= LAST_VECTOR_VALUETYPE) ||
- isExtendedVT(VT);
+ (VT & VectorMask);
}
-
+
/// MVT::getVectorElementType - Given a vector type, return the type of
/// each element.
static inline ValueType getVectorElementType(ValueType VT) {
+ assert(isVector(VT) && "Invalid vector type!");
switch (VT) {
default:
- if (isExtendedVT(VT))
- return VT & SimpleTypeMask;
- assert(0 && "Invalid vector type!");
+ assert(isExtendedVT(VT) && "Unknown simple vector type!");
+ return VT & ElementMask;
case v8i8 :
case v16i8: return i8;
case v4i16:
- case v8i16: return i16;
+ case v8i16: return i16;
case v2i32:
case v3i32:
case v4i32: return i32;
@@ -152,20 +176,20 @@
case v2f64: return f64;
}
}
-
+
/// MVT::getVectorNumElements - Given a vector type, return the
/// number of elements it contains.
static inline unsigned getVectorNumElements(ValueType VT) {
+ assert(isVector(VT) && "Invalid vector type!");
switch (VT) {
default:
- if (isExtendedVT(VT))
- return ((VT & ~SimpleTypeMask) >> SimpleTypeBits) - 1;
- assert(0 && "Invalid vector type!");
+ assert(isExtendedVT(VT) && "Unknown simple vector type!");
+ return ((VT & VectorMask) >> (32 - VectorBits)) - 1;
case v16i8: return 16;
case v8i8 :
case v8i16: return 8;
case v4i16:
- case v4i32:
+ case v4i32:
case v4f32: return 4;
case v3i32:
case v3f32: return 3;
@@ -176,17 +200,20 @@
case v1i64: return 1;
}
}
-
+
/// MVT::getSizeInBits - Return the size of the specified value type
/// in bits.
///
static inline unsigned getSizeInBits(ValueType VT) {
switch (VT) {
default:
- if (isExtendedVT(VT))
+ assert(isExtendedVT(VT) && "ValueType has no known size!");
+ if (isVector(VT))
return getSizeInBits(getVectorElementType(VT)) *
getVectorNumElements(VT);
- assert(0 && "ValueType has no known size!");
+ if (isInteger(VT))
+ return ((VT & PrecisionMask) >> SimpleTypeBits) + 1;
+ assert(0 && "Unknown value type!");
case MVT::i1 : return 1;
case MVT::i8 : return 8;
case MVT::i16 : return 16;
@@ -196,7 +223,7 @@
case MVT::i64 :
case MVT::v8i8:
case MVT::v4i16:
- case MVT::v2i32:
+ case MVT::v2i32:
case MVT::v1i64:
case MVT::v2f32: return 64;
case MVT::f80 : return 80;
@@ -204,7 +231,7 @@
case MVT::v3f32: return 96;
case MVT::f128:
case MVT::ppcf128:
- case MVT::i128:
+ case MVT::i128:
case MVT::v16i8:
case MVT::v8i16:
case MVT::v4i32:
@@ -213,7 +240,46 @@
case MVT::v2f64: return 128;
}
}
-
+
+ /// MVT::getIntegerType - Returns the ValueType that represents an integer
+ /// with the given number of bits.
+ ///
+ static inline ValueType getIntegerType(unsigned BitWidth) {
+ switch (BitWidth) {
+ default:
+ break;
+ case 1:
+ return MVT::i1;
+ case 8:
+ return MVT::i8;
+ case 16:
+ return MVT::i16;
+ case 32:
+ return MVT::i32;
+ case 64:
+ return MVT::i64;
+ case 128:
+ return MVT::i128;
+ }
+ ValueType Result = iAny |
+ (((BitWidth - 1) << SimpleTypeBits) & PrecisionMask);
+ assert(getSizeInBits(Result) == BitWidth && "Bad bit width!");
+ return Result;
+ }
+
+ /// MVT::RoundIntegerType - Rounds the bit-width of the given integer
+ /// ValueType up to the nearest power of two (and at least to eight),
+ /// and returns the integer ValueType with that number of bits.
+ ///
+ static inline ValueType RoundIntegerType(ValueType VT) {
+ assert(isInteger(VT) && !isVector(VT) && "Invalid integer type!");
+ unsigned BitWidth = getSizeInBits(VT);
+ if (BitWidth <= 8)
+ return MVT::i8;
+ else
+ return getIntegerType(1 << Log2_32_Ceil(BitWidth));
+ }
+
/// MVT::getVectorType - Returns the ValueType that represents a vector
/// NumElements in length, where each element is of type VT.
///
@@ -247,7 +313,7 @@
if (NumElements == 2) return MVT::v2f64;
break;
}
- ValueType Result = VT | ((NumElements + 1) << SimpleTypeBits);
+ ValueType Result = VT | ((NumElements + 1) << (32 - VectorBits));
assert(getVectorElementType(Result) == VT &&
"Bad vector element type!");
assert(getVectorNumElements(Result) == NumElements &&
@@ -268,8 +334,8 @@
case 16: return v16i8;
}
}
-
-
+
+
/// MVT::getIntVTBitMask - Return an integer with 1's every place there are
/// bits in the specified integer value type.
static inline uint64_t getIntVTBitMask(ValueType VT) {
@@ -291,7 +357,7 @@
/// to the specified ValueType. For integer types, this returns an unsigned
/// type. Note that this will abort for types that cannot be represented.
const Type *getTypeForValueType(ValueType VT);
-
+
/// MVT::getValueType - Return the value type corresponding to the specified
/// type. This returns all pointers as MVT::iPTR. If HandleUnknown is true,
/// unknown types are returned as Other, otherwise they are invalid.
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=43030&r1=43029&r2=43030&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Tue Oct 16 04:56:48 2007
@@ -150,7 +150,13 @@
}
LegalizeAction getTypeAction(MVT::ValueType VT) const {
- if (MVT::isExtendedVT(VT)) return Expand;
+ if (MVT::isExtendedVT(VT)) {
+ if (MVT::isVector(VT)) return Expand;
+ if (MVT::isInteger(VT))
+ // First promote to a power-of-two size, then expand if necessary.
+ return VT == MVT::RoundIntegerType(VT) ? Expand : Promote;
+ assert(0 && "Unsupported extended type!");
+ }
return (LegalizeAction)((ValueTypeActions[VT>>4] >> ((2*VT) & 31)) & 3);
}
void setTypeAction(MVT::ValueType VT, LegalizeAction Action) {
@@ -179,19 +185,34 @@
/// to get to the smaller register. For illegal floating point types, this
/// returns the integer type to transform to.
MVT::ValueType getTypeToTransformTo(MVT::ValueType VT) const {
- if (MVT::isExtendedVT(VT))
+ if (!MVT::isExtendedVT(VT)) {
+ MVT::ValueType NVT = TransformToType[VT];
+ assert(getTypeAction(NVT) != Promote &&
+ "Promote may not follow Expand or Promote");
+ return NVT;
+ }
+
+ if (MVT::isVector(VT))
return MVT::getVectorType(MVT::getVectorElementType(VT),
MVT::getVectorNumElements(VT) / 2);
-
- return TransformToType[VT];
+ if (MVT::isInteger(VT)) {
+ MVT::ValueType NVT = MVT::RoundIntegerType(VT);
+ if (NVT == VT)
+ // Size is a power of two - expand to half the size.
+ return MVT::getIntegerType(MVT::getSizeInBits(VT) / 2);
+ else
+ // Promote to a power of two size, avoiding multi-step promotion.
+ return getTypeAction(NVT) == Promote ? getTypeToTransformTo(NVT) : NVT;
+ }
+ assert(0 && "Unsupported extended type!");
}
-
+
/// getTypeToExpandTo - For types supported by the target, this is an
/// identity function. For types that must be expanded (i.e. integer types
/// that are larger than the largest integer register or illegal floating
/// point types), this returns the largest legal type it will be expanded to.
MVT::ValueType getTypeToExpandTo(MVT::ValueType VT) const {
- assert(!MVT::isExtendedVT(VT));
+ assert(!MVT::isVector(VT));
while (true) {
switch (getTypeAction(VT)) {
case Legal:
@@ -252,7 +273,7 @@
/// expanded to some other code sequence, or the target has a custom expander
/// for it.
LegalizeAction getOperationAction(unsigned Op, MVT::ValueType VT) const {
- if (MVT::isExtendedVT(VT)) return Expand;
+ if (MVT::isExtendedVT(VT)) return getTypeAction(VT);
return (LegalizeAction)((OpActions[Op] >> (2*VT)) & 3);
}
@@ -268,7 +289,7 @@
/// expanded to some other code sequence, or the target has a custom expander
/// for it.
LegalizeAction getLoadXAction(unsigned LType, MVT::ValueType VT) const {
- if (MVT::isExtendedVT(VT)) return Expand;
+ if (MVT::isExtendedVT(VT)) return getTypeAction(VT);
return (LegalizeAction)((LoadXActions[LType] >> (2*VT)) & 3);
}
@@ -284,7 +305,7 @@
/// expanded to some other code sequence, or the target has a custom expander
/// for it.
LegalizeAction getStoreXAction(MVT::ValueType VT) const {
- if (MVT::isExtendedVT(VT)) return Expand;
+ if (MVT::isExtendedVT(VT)) return getTypeAction(VT);
return (LegalizeAction)((StoreXActions >> (2*VT)) & 3);
}
@@ -300,7 +321,7 @@
/// for it.
LegalizeAction
getIndexedLoadAction(unsigned IdxMode, MVT::ValueType VT) const {
- if (MVT::isExtendedVT(VT)) return Expand;
+ if (MVT::isExtendedVT(VT)) return getTypeAction(VT);
return (LegalizeAction)((IndexedModeActions[0][IdxMode] >> (2*VT)) & 3);
}
@@ -317,7 +338,7 @@
/// for it.
LegalizeAction
getIndexedStoreAction(unsigned IdxMode, MVT::ValueType VT) const {
- if (MVT::isExtendedVT(VT)) return Expand;
+ if (MVT::isExtendedVT(VT)) return getTypeAction(VT);
return (LegalizeAction)((IndexedModeActions[1][IdxMode] >> (2*VT)) & 3);
}
@@ -385,13 +406,15 @@
MVT::ValueType getRegisterType(MVT::ValueType VT) const {
if (!MVT::isExtendedVT(VT))
return RegisterTypeForVT[VT];
-
- MVT::ValueType VT1, RegisterVT;
- unsigned NumIntermediates;
- (void)getVectorTypeBreakdown(VT, VT1, NumIntermediates, RegisterVT);
- return RegisterVT;
+ if (MVT::isVector(VT)) {
+ MVT::ValueType VT1, RegisterVT;
+ unsigned NumIntermediates;
+ (void)getVectorTypeBreakdown(VT, VT1, NumIntermediates, RegisterVT);
+ return RegisterVT;
+ }
+ assert(0 && "Unsupported extended type!");
}
-
+
/// getNumRegisters - Return the number of registers that this ValueType will
/// eventually require. This is one for any types promoted to live in larger
/// registers, but may be more than one for types (like i64) that are split
@@ -399,10 +422,12 @@
unsigned getNumRegisters(MVT::ValueType VT) const {
if (!MVT::isExtendedVT(VT))
return NumRegistersForVT[VT];
-
- MVT::ValueType VT1, VT2;
- unsigned NumIntermediates;
- return getVectorTypeBreakdown(VT, VT1, NumIntermediates, VT2);
+ if (MVT::isVector(VT)) {
+ MVT::ValueType VT1, VT2;
+ unsigned NumIntermediates;
+ return getVectorTypeBreakdown(VT, VT1, NumIntermediates, VT2);
+ }
+ assert(0 && "Unsupported extended type!");
}
/// hasTargetDAGCombine - If true, the target has custom DAG combine
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=43030&r1=43029&r2=43030&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Oct 16 04:56:48 2007
@@ -28,6 +28,7 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include
@@ -846,6 +847,7 @@
}
SDOperand SelectionDAG::getValueType(MVT::ValueType VT) {
+ assert(!MVT::isExtendedVT(VT) && "Expecting a simple value type!");
if ((unsigned)VT >= ValueTypeNodes.size())
ValueTypeNodes.resize(VT+1);
if (ValueTypeNodes[VT] == 0) {
@@ -1734,7 +1736,8 @@
assert(MVT::isInteger(VT) && MVT::isInteger(Operand.getValueType()) &&
"Invalid SIGN_EXTEND!");
if (Operand.getValueType() == VT) return Operand; // noop extension
- assert(Operand.getValueType() < VT && "Invalid sext node, dst < src!");
+ assert(MVT::getSizeInBits(Operand.getValueType()) < MVT::getSizeInBits(VT)
+ && "Invalid sext node, dst < src!");
if (OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ZERO_EXTEND)
return getNode(OpOpcode, VT, Operand.Val->getOperand(0));
break;
@@ -1742,7 +1745,8 @@
assert(MVT::isInteger(VT) && MVT::isInteger(Operand.getValueType()) &&
"Invalid ZERO_EXTEND!");
if (Operand.getValueType() == VT) return Operand; // noop extension
- assert(Operand.getValueType() < VT && "Invalid zext node, dst < src!");
+ assert(MVT::getSizeInBits(Operand.getValueType()) < MVT::getSizeInBits(VT)
+ && "Invalid zext node, dst < src!");
if (OpOpcode == ISD::ZERO_EXTEND) // (zext (zext x)) -> (zext x)
return getNode(ISD::ZERO_EXTEND, VT, Operand.Val->getOperand(0));
break;
@@ -1750,7 +1754,8 @@
assert(MVT::isInteger(VT) && MVT::isInteger(Operand.getValueType()) &&
"Invalid ANY_EXTEND!");
if (Operand.getValueType() == VT) return Operand; // noop extension
- assert(Operand.getValueType() < VT && "Invalid anyext node, dst < src!");
+ assert(MVT::getSizeInBits(Operand.getValueType()) < MVT::getSizeInBits(VT)
+ && "Invalid anyext node, dst < src!");
if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND)
// (ext (zext x)) -> (zext x) and (ext (sext x)) -> (sext x)
return getNode(OpOpcode, VT, Operand.Val->getOperand(0));
@@ -1759,15 +1764,18 @@
assert(MVT::isInteger(VT) && MVT::isInteger(Operand.getValueType()) &&
"Invalid TRUNCATE!");
if (Operand.getValueType() == VT) return Operand; // noop truncate
- assert(Operand.getValueType() > VT && "Invalid truncate node, src < dst!");
+ assert(MVT::getSizeInBits(Operand.getValueType()) > MVT::getSizeInBits(VT)
+ && "Invalid truncate node, src < dst!");
if (OpOpcode == ISD::TRUNCATE)
return getNode(ISD::TRUNCATE, VT, Operand.Val->getOperand(0));
else if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND ||
OpOpcode == ISD::ANY_EXTEND) {
// If the source is smaller than the dest, we still need an extend.
- if (Operand.Val->getOperand(0).getValueType() < VT)
+ if (MVT::getSizeInBits(Operand.Val->getOperand(0).getValueType())
+ < MVT::getSizeInBits(VT))
return getNode(OpOpcode, VT, Operand.Val->getOperand(0));
- else if (Operand.Val->getOperand(0).getValueType() > VT)
+ else if (MVT::getSizeInBits(Operand.Val->getOperand(0).getValueType())
+ > MVT::getSizeInBits(VT))
return getNode(ISD::TRUNCATE, VT, Operand.Val->getOperand(0));
else
return Operand.Val->getOperand(0);
@@ -1874,7 +1882,8 @@
assert(VT == N1.getValueType() && "Not an inreg round!");
assert(MVT::isFloatingPoint(VT) && MVT::isFloatingPoint(EVT) &&
"Cannot FP_ROUND_INREG integer types");
- assert(EVT <= VT && "Not rounding down!");
+ assert(MVT::getSizeInBits(EVT) <= MVT::getSizeInBits(VT) &&
+ "Not rounding down!");
break;
}
case ISD::AssertSext:
@@ -1884,7 +1893,8 @@
assert(VT == N1.getValueType() && "Not an inreg extend!");
assert(MVT::isInteger(VT) && MVT::isInteger(EVT) &&
"Cannot *_EXTEND_INREG FP types");
- assert(EVT <= VT && "Not extending!");
+ assert(MVT::getSizeInBits(EVT) <= MVT::getSizeInBits(VT) &&
+ "Not extending!");
}
default: break;
@@ -2299,7 +2309,8 @@
if (MVT::isVector(VT))
assert(EVT == MVT::getVectorElementType(VT) && "Invalid vector extload!");
else
- assert(EVT < VT && "Should only be an extending load, not truncating!");
+ assert(MVT::getSizeInBits(EVT) < MVT::getSizeInBits(VT) &&
+ "Should only be an extending load, not truncating!");
assert((ExtType == ISD::EXTLOAD || MVT::isInteger(VT)) &&
"Cannot sign/zero extend a FP/Vector load!");
assert(MVT::isInteger(VT) == MVT::isInteger(EVT) &&
@@ -2415,7 +2426,8 @@
MVT::ValueType VT = Val.getValueType();
bool isTrunc = VT != SVT;
- assert(VT > SVT && "Not a truncation?");
+ assert(MVT::getSizeInBits(VT) > MVT::getSizeInBits(SVT) &&
+ "Not a truncation?");
assert(MVT::isInteger(VT) == MVT::isInteger(SVT) &&
"Can't do FP-INT conversion!");
@@ -2648,18 +2660,7 @@
}
SDVTList SelectionDAG::getVTList(MVT::ValueType VT) {
- if (!MVT::isExtendedVT(VT))
- return makeVTList(SDNode::getValueTypeList(VT), 1);
-
- for (std::list >::iterator I = VTList.begin(),
- E = VTList.end(); I != E; ++I) {
- if (I->size() == 1 && (*I)[0] == VT)
- return makeVTList(&(*I)[0], 1);
- }
- std::vector V;
- V.push_back(VT);
- VTList.push_front(V);
- return makeVTList(&(*VTList.begin())[0], 1);
+ return makeVTList(SDNode::getValueTypeList(VT), 1);
}
SDVTList SelectionDAG::getVTList(MVT::ValueType VT1, MVT::ValueType VT2) {
@@ -3427,11 +3428,16 @@
/// getValueTypeList - Return a pointer to the specified value type.
///
MVT::ValueType *SDNode::getValueTypeList(MVT::ValueType VT) {
- static MVT::ValueType VTs[MVT::LAST_VALUETYPE];
- VTs[VT] = VT;
- return &VTs[VT];
+ if (MVT::isExtendedVT(VT)) {
+ static std::set EVTs;
+ return (MVT::ValueType *)&(*EVTs.insert(VT).first);
+ } else {
+ static MVT::ValueType VTs[MVT::LAST_VALUETYPE];
+ VTs[VT] = VT;
+ return &VTs[VT];
+ }
}
-
+
/// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
/// indicated value. This method ignores uses of other values defined by this
/// operation.
Modified: llvm/trunk/lib/VMCore/ValueTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ValueTypes.cpp?rev=43030&r1=43029&r2=43030&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/ValueTypes.cpp (original)
+++ llvm/trunk/lib/VMCore/ValueTypes.cpp Tue Oct 16 04:56:48 2007
@@ -22,9 +22,11 @@
std::string MVT::getValueTypeString(MVT::ValueType VT) {
switch (VT) {
default:
- if (isExtendedVT(VT))
+ if (isVector(VT))
return "v" + utostr(getVectorNumElements(VT)) +
getValueTypeString(getVectorElementType(VT));
+ if (isInteger(VT))
+ return "i" + utostr(getSizeInBits(VT));
assert(0 && "Invalid ValueType!");
case MVT::i1: return "i1";
case MVT::i8: return "i8";
@@ -62,9 +64,11 @@
const Type *MVT::getTypeForValueType(MVT::ValueType VT) {
switch (VT) {
default:
- if (isExtendedVT(VT))
+ if (isVector(VT))
return VectorType::get(getTypeForValueType(getVectorElementType(VT)),
getVectorNumElements(VT));
+ if (isInteger(VT))
+ return IntegerType::get(getSizeInBits(VT));
assert(0 && "ValueType does not correspond to LLVM type!");
case MVT::isVoid:return Type::VoidTy;
case MVT::i1: return Type::Int1Ty;
@@ -105,19 +109,7 @@
case Type::VoidTyID:
return MVT::isVoid;
case Type::IntegerTyID:
- switch (cast(Ty)->getBitWidth()) {
- default:
- // FIXME: Return MVT::iANY.
- if (HandleUnknown) return MVT::Other;
- assert(0 && "Invalid width for value type");
- case 1: return MVT::i1;
- case 8: return MVT::i8;
- case 16: return MVT::i16;
- case 32: return MVT::i32;
- case 64: return MVT::i64;
- case 128: return MVT::i128;
- }
- break;
+ return getIntegerType(cast(Ty)->getBitWidth());
case Type::FloatTyID: return MVT::f32;
case Type::DoubleTyID: return MVT::f64;
case Type::X86_FP80TyID: return MVT::f80;
From baldrick at free.fr Tue Oct 16 08:34:12 2007
From: baldrick at free.fr (Duncan Sands)
Date: Tue, 16 Oct 2007 13:34:12 -0000
Subject: [llvm-commits] [llvm] r43031 -
/llvm/trunk/include/llvm/CodeGen/ValueTypes.h
Message-ID: <200710161334.l9GDYChk032490@zion.cs.uiuc.edu>
Author: baldrick
Date: Tue Oct 16 08:34:11 2007
New Revision: 43031
URL: http://llvm.org/viewvc/llvm-project?rev=43031&view=rev
Log:
Document the fact that the verifier currently requires the
top bit of a ValueType to be zero. Enforce this by ensuring
an assertion failure if someone tries to create a ValueType
without this property. I chose this minimal approach rather
than a more official integration of the notion of reserved
bits into ValueType because I'm hoping that the verifier will
be changed to no longer require this :)
Modified:
llvm/trunk/include/llvm/CodeGen/ValueTypes.h
Modified: llvm/trunk/include/llvm/CodeGen/ValueTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ValueTypes.h?rev=43031&r1=43030&r2=43031&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ValueTypes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ValueTypes.h Tue Oct 16 08:34:11 2007
@@ -107,7 +107,9 @@
///
/// 31--------------16-----------8-------------0
/// | Vector length | Precision | Simple type |
- /// | Vector element |
+ /// | | Vector element |
+ ///
+ /// Note that the verifier currently requires the top bit to be zero.
typedef uint32_t ValueType;
@@ -313,7 +315,8 @@
if (NumElements == 2) return MVT::v2f64;
break;
}
- ValueType Result = VT | ((NumElements + 1) << (32 - VectorBits));
+ // Set the length with the top bit forced to zero (needed by the verifier).
+ ValueType Result = VT | (((NumElements + 1) << (33 - VectorBits)) >> 1);
assert(getVectorElementType(Result) == VT &&
"Bad vector element type!");
assert(getVectorNumElements(Result) == NumElements &&
From asl at math.spbu.ru Tue Oct 16 11:28:47 2007
From: asl at math.spbu.ru (Anton Korobeynikov)
Date: Tue, 16 Oct 2007 11:28:47 -0500
Subject: [llvm-commits] CVS: llvm-www/releases/download.html
Message-ID: <200710161628.l9GGSlBo007128@zion.cs.uiuc.edu>
Changes in directory llvm-www/releases:
download.html updated: 1.46 -> 1.47
---
Log message:
Add links to pre-built packages for FreeBSD and ArchLinux
---
Diffs of the changes: (+5 -2)
download.html | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
Index: llvm-www/releases/download.html
diff -u llvm-www/releases/download.html:1.46 llvm-www/releases/download.html:1.47
--- llvm-www/releases/download.html:1.46 Thu Sep 27 01:18:06 2007
+++ llvm-www/releases/download.html Tue Oct 16 11:28:11 2007
@@ -41,13 +41,16 @@
Here are additional useful binaries:
From sabre at nondot.org Tue Oct 16 13:00:19 2007
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 16 Oct 2007 18:00:19 -0000
Subject: [llvm-commits] [llvm] r43032 - in /llvm/trunk:
lib/Target/PowerPC/PPCRegisterInfo.cpp
test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll
Message-ID: <200710161800.l9GI0JHM010203@zion.cs.uiuc.edu>
Author: lattner
Date: Tue Oct 16 13:00:18 2007
New Revision: 43032
URL: http://llvm.org/viewvc/llvm-project?rev=43032&view=rev
Log:
Fix a bug handling frame references in ppc inline asm when the frame offset
doesn't fit into 16 bits.
Added:
llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll
Modified:
llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp
Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=43032&r1=43031&r2=43032&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Tue Oct 16 13:00:18 2007
@@ -722,18 +722,19 @@
MachineFrameInfo *MFI = MF.getFrameInfo();
// Find out which operand is the frame index.
- unsigned i = 0;
- while (!MI.getOperand(i).isFrameIndex()) {
- ++i;
- assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
+ unsigned FIOperandNo = 0;
+ while (!MI.getOperand(FIOperandNo).isFrameIndex()) {
+ ++FIOperandNo;
+ assert(FIOperandNo != MI.getNumOperands() &&
+ "Instr doesn't have FrameIndex operand!");
}
// Take into account whether it's an add or mem instruction
- unsigned OffIdx = (i == 2) ? 1 : 2;
+ unsigned OffsetOperandNo = (FIOperandNo == 2) ? 1 : 2;
if (MI.getOpcode() == TargetInstrInfo::INLINEASM)
- OffIdx = i-1;
+ OffsetOperandNo = FIOperandNo-1;
// Get the frame index.
- int FrameIndex = MI.getOperand(i).getFrameIndex();
+ int FrameIndex = MI.getOperand(FIOperandNo).getFrameIndex();
// Get the frame pointer save index. Users of this index are primarily
// DYNALLOC instructions.
@@ -750,7 +751,8 @@
}
// Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP).
- MI.getOperand(i).ChangeToRegister(hasFP(MF) ? PPC::R31 : PPC::R1, false);
+ MI.getOperand(FIOperandNo).ChangeToRegister(hasFP(MF) ? PPC::R31 : PPC::R1,
+ false);
// Figure out if the offset in the instruction is shifted right two bits. This
// is true for instructions like "STD", which the machine implicitly adds two
@@ -767,37 +769,44 @@
// Now add the frame object offset to the offset from r1.
int Offset = MFI->getObjectOffset(FrameIndex);
-
if (!isIXAddr)
- Offset += MI.getOperand(OffIdx).getImmedValue();
+ Offset += MI.getOperand(OffsetOperandNo).getImmedValue();
else
- Offset += MI.getOperand(OffIdx).getImmedValue() << 2;
+ Offset += MI.getOperand(OffsetOperandNo).getImmedValue() << 2;
// If we're not using a Frame Pointer that has been set to the value of the
// SP before having the stack size subtracted from it, then add the stack size
// to Offset to get the correct offset.
Offset += MFI->getStackSize();
- if (!isInt16(Offset)) {
+ if (isInt16(Offset)) {
+ if (isIXAddr) {
+ assert((Offset & 3) == 0 && "Invalid frame offset!");
+ Offset >>= 2; // The actual encoded value has the low two bits zero.
+ }
+ MI.getOperand(OffsetOperandNo).ChangeToImmediate(Offset);
+ } else {
// Insert a set of r0 with the full offset value before the ld, st, or add
BuildMI(MBB, II, TII.get(PPC::LIS), PPC::R0).addImm(Offset >> 16);
BuildMI(MBB, II, TII.get(PPC::ORI), PPC::R0).addReg(PPC::R0).addImm(Offset);
- // convert into indexed form of the instruction
+ // Convert into indexed form of the instruction
// sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
// addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
- assert(ImmToIdxMap.count(OpC) &&
- "No indexed form of load or store available!");
- unsigned NewOpcode = ImmToIdxMap.find(OpC)->second;
- MI.setInstrDescriptor(TII.get(NewOpcode));
- MI.getOperand(1).ChangeToRegister(MI.getOperand(i).getReg(), false);
- MI.getOperand(2).ChangeToRegister(PPC::R0, false);
- } else {
- if (isIXAddr) {
- assert((Offset & 3) == 0 && "Invalid frame offset!");
- Offset >>= 2; // The actual encoded value has the low two bits zero.
+ unsigned OperandBase;
+ if (OpC != TargetInstrInfo::INLINEASM) {
+ assert(ImmToIdxMap.count(OpC) &&
+ "No indexed form of load or store available!");
+ unsigned NewOpcode = ImmToIdxMap.find(OpC)->second;
+ MI.setInstrDescriptor(TII.get(NewOpcode));
+ OperandBase = 1;
+ } else {
+ OperandBase = OffsetOperandNo;
}
- MI.getOperand(OffIdx).ChangeToImmediate(Offset);
+
+ unsigned StackReg = MI.getOperand(FIOperandNo).getReg();
+ MI.getOperand(OperandBase).ChangeToRegister(StackReg, false);
+ MI.getOperand(OperandBase+1).ChangeToRegister(PPC::R0, false);
}
}
Added: llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll?rev=43032&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll Tue Oct 16 13:00:18 2007
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | llc -march=ppc32
+; rdar://5538377
+
+ %struct.disk_unsigned = type { i32 }
+ %struct._StorePageMax = type { %struct.disk_unsigned, %struct.disk_unsigned, [65536 x i8] }
+
+define i32 @test() {
+entry:
+ %data = alloca i32 ; [#uses=1]
+ %compressedPage = alloca %struct._StorePageMax ; <%struct._StorePageMax*> [#uses=0]
+ %tmp107 = call i32 asm "lwbrx $0, $2, $1", "=r,r,bO,*m"( i8* null, i32 0, i32* %data ) ; [#uses=0]
+ unreachable
+}
+
From dalej at apple.com Tue Oct 16 13:09:09 2007
From: dalej at apple.com (Dale Johannesen)
Date: Tue, 16 Oct 2007 18:09:09 -0000
Subject: [llvm-commits] [llvm] r43033 -
/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
Message-ID: <200710161809.l9GI999L010472@zion.cs.uiuc.edu>
Author: johannes
Date: Tue Oct 16 13:09:08 2007
New Revision: 43033
URL: http://llvm.org/viewvc/llvm-project?rev=43033&view=rev
Log:
Check for invalid cc's in f80 select.
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=43033&r1=43032&r2=43033&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Oct 16 13:09:08 2007
@@ -4139,6 +4139,8 @@
IllegalFPCMov = !hasFPCMov(cast(CC)->getSignExtended());
else if (VT == MVT::f64 && !X86ScalarSSEf64)
IllegalFPCMov = !hasFPCMov(cast(CC)->getSignExtended());
+ else if (VT == MVT::f80)
+ IllegalFPCMov = !hasFPCMov(cast(CC)->getSignExtended());
if ((Opc == X86ISD::CMP ||
Opc == X86ISD::COMI ||
Opc == X86ISD::UCOMI) && !IllegalFPCMov) {
From dalej at apple.com Tue Oct 16 13:10:14 2007
From: dalej at apple.com (Dale Johannesen)
Date: Tue, 16 Oct 2007 18:10:14 -0000
Subject: [llvm-commits] [llvm] r43034 -
/llvm/trunk/test/CodeGen/X86/2007-10-16-fp80_select.ll
Message-ID: <200710161810.l9GIAEHe010520@zion.cs.uiuc.edu>
Author: johannes
Date: Tue Oct 16 13:10:14 2007
New Revision: 43034
URL: http://llvm.org/viewvc/llvm-project?rev=43034&view=rev
Log:
New test for svn rev 43033, radar 5538745.
Added:
llvm/trunk/test/CodeGen/X86/2007-10-16-fp80_select.ll
Added: llvm/trunk/test/CodeGen/X86/2007-10-16-fp80_select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-10-16-fp80_select.ll?rev=43034&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2007-10-16-fp80_select.ll (added)
+++ llvm/trunk/test/CodeGen/X86/2007-10-16-fp80_select.ll Tue Oct 16 13:10:14 2007
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s | llc -march=x86
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+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-darwin9"
+ %struct.wxPoint2DInt = type { i32, i32 }
+
+define x86_fp80 @_ZNK12wxPoint2DInt14GetVectorAngleEv(%struct.wxPoint2DInt* %this) {
+entry:
+ br i1 false, label %cond_true, label %UnifiedReturnBlock
+
+cond_true: ; preds = %entry
+ %tmp8 = load i32* null, align 4 ; [#uses=1]
+ %tmp9 = icmp sgt i32 %tmp8, -1 ; [#uses=1]
+ %retval = select i1 %tmp9, x86_fp80 0xK4005B400000000000000, x86_fp80 0xK40078700000000000000 ; [#uses=1]
+ ret x86_fp80 %retval
+
+UnifiedReturnBlock: ; preds = %entry
+ ret x86_fp80 0xK4005B400000000000000
+}
From evan.cheng at apple.com Tue Oct 16 14:29:47 2007
From: evan.cheng at apple.com (Evan Cheng)
Date: Tue, 16 Oct 2007 19:29:47 -0000
Subject: [llvm-commits] [llvm] r43035 - in /llvm/trunk:
lib/CodeGen/SimpleRegisterCoalescing.cpp
test/CodeGen/X86/2007-10-16-IllegalAsm.ll
Message-ID: <200710161929.l9GJTl8o012981@zion.cs.uiuc.edu>
Author: evancheng
Date: Tue Oct 16 14:29:47 2007
New Revision: 43035
URL: http://llvm.org/viewvc/llvm-project?rev=43035&view=rev
Log:
Fix PR1734.
Added:
llvm/trunk/test/CodeGen/X86/2007-10-16-IllegalAsm.ll
Modified:
llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=43035&r1=43034&r2=43035&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Tue Oct 16 14:29:47 2007
@@ -459,7 +459,7 @@
std::swap(repSrcReg, repDstReg);
std::swap(ResSrcInt, ResDstInt);
}
- SubRegIdxes.push_back(std::make_pair(repSrcReg,
+ SubRegIdxes.push_back(std::make_pair(DstReg,
CopyMI->getOperand(2).getImm()));
}
Added: llvm/trunk/test/CodeGen/X86/2007-10-16-IllegalAsm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-10-16-IllegalAsm.ll?rev=43035&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2007-10-16-IllegalAsm.ll (added)
+++ llvm/trunk/test/CodeGen/X86/2007-10-16-IllegalAsm.ll Tue Oct 16 14:29:47 2007
@@ -0,0 +1,272 @@
+; RUN: llvm-as < %s | llc -mtriple=x86_64-linux-gnu | grep movb | not grep x
+; PR1734
+
+ %struct.CUMULATIVE_ARGS = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }
+ %struct.eh_status = type opaque
+ %struct.emit_status = type { i32, i32, %struct.rtx_def*, %struct.rtx_def*, %struct.sequence_stack*, i32, %struct.location_t, i32, i8*, %struct.rtx_def** }
+ %struct.expr_status = type { i32, i32, i32, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def* }
+ %struct.function = type { %struct.eh_status*, %struct.expr_status*, %struct.emit_status*, %struct.varasm_status*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.function*, i32, i32, i32, i32, %struct.rtx_def*, %struct.CUMULATIVE_ARGS, %struct.rtx_def*, %struct.rtx_def*, %struct.initial_value_struct*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, i8, i32, i64, %struct.tree_node*, %struct.tree_node*, %struct.rtx_def*, %struct.varray_head_tag*, %struct.temp_slot*, i32, %struct.var_refs_queue*, i32, i32, %struct.rtvec_def*, %struct.tree_node*, i32, i32, i32, %struct.machine_function*, i32, i32, i8, i8, %struct.language_function*, %struct.rtx_def*, i32, i32, i32, i32, %struct.location_t, %struct.varray_head_tag*, %struct.tree_node*, %struct.tree_node*, i8, i8, i8 }
+ %struct.initial_value_struct = type opaque
+ %struct.lang_decl = type opaque
+ %struct.lang_type = type opaque
+ %struct.language_function = type opaque
+ %struct.location_t = type { i8*, i32 }
+ %struct.machine_function = type { %struct.stack_local_entry*, i8*, %struct.rtx_def*, i32, i32, i32, i32, i32 }
+ %struct.rtunion = type { i8* }
+ %struct.rtvec_def = type { i32, [1 x %struct.rtx_def*] }
+ %struct.rtx_def = type { i16, i8, i8, %struct.u }
+ %struct.sequence_stack = type { %struct.rtx_def*, %struct.rtx_def*, %struct.sequence_stack* }
+ %struct.stack_local_entry = type opaque
+ %struct.temp_slot = type opaque
+ %struct.tree_common = type { %struct.tree_node*, %struct.tree_node*, %union.tree_ann_d*, i8, i8, i8, i8, i8 }
+ %struct.tree_decl = type { %struct.tree_common, %struct.location_t, i32, %struct.tree_node*, i8, i8, i8, i8, i8, i8, i8, i8, i32, %struct.tree_decl_u1, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.rtx_def*, i32, %struct.tree_decl_u2, %struct.tree_node*, %struct.tree_node*, i64, %struct.lang_decl* }
+ %struct.tree_decl_u1 = type { i64 }
+ %struct.tree_decl_u2 = type { %struct.function* }
+ %struct.tree_node = type { %struct.tree_decl }
+ %struct.tree_type = type { %struct.tree_common, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, i32, i16, i8, i8, i32, %struct.tree_node*, %struct.tree_node*, %struct.rtunion, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, i64, %struct.lang_type* }
+ %struct.u = type { [1 x %struct.rtunion] }
+ %struct.var_refs_queue = type { %struct.rtx_def*, i32, i32, %struct.var_refs_queue* }
+ %struct.varasm_status = type opaque
+ %struct.varray_data = type { [1 x i64] }
+ %struct.varray_head_tag = type { i64, i64, i32, i8*, %struct.varray_data }
+ %union.tree_ann_d = type opaque
+ at .str = external constant [28 x i8] ; <[28 x i8]*> [#uses=1]
+ at tree_code_type = external constant [0 x i32] ; <[0 x i32]*> [#uses=5]
+ at global_trees = external global [47 x %struct.tree_node*] ; <[47 x %struct.tree_node*]*> [#uses=1]
+ at mode_size = external global [48 x i8] ; <[48 x i8]*> [#uses=1]
+ at __FUNCTION__.22683 = external constant [12 x i8] ; <[12 x i8]*> [#uses=1]
+
+define void @layout_type(%struct.tree_node* %type) {
+entry:
+ %tmp15 = icmp eq %struct.tree_node* %type, null ; [#uses=1]
+ br i1 %tmp15, label %cond_true, label %cond_false
+
+cond_true: ; preds = %entry
+ tail call void @fancy_abort( i8* getelementptr ([28 x i8]* @.str, i32 0, i64 0), i32 1713, i8* getelementptr ([12 x i8]* @__FUNCTION__.22683, i32 0, i32 0) )
+ unreachable
+
+cond_false: ; preds = %entry
+ %tmp19 = load %struct.tree_node** getelementptr ([47 x %struct.tree_node*]* @global_trees, i32 0, i64 0), align 8 ; <%struct.tree_node*> [#uses=1]
+ %tmp21 = icmp eq %struct.tree_node* %tmp19, %type ; [#uses=1]
+ br i1 %tmp21, label %UnifiedReturnBlock, label %cond_next25
+
+cond_next25: ; preds = %cond_false
+ %tmp30 = getelementptr %struct.tree_node* %type, i32 0, i32 0, i32 0, i32 3 ; [#uses=1]
+ %tmp3031 = bitcast i8* %tmp30 to i32* ; [#uses=6]
+ %tmp32 = load i32* %tmp3031, align 8 ; [#uses=3]
+ %tmp3435 = trunc i32 %tmp32 to i8 ; [#uses=3]
+ %tmp34353637 = zext i8 %tmp3435 to i64 ; [#uses=1]
+ %tmp38 = getelementptr [0 x i32]* @tree_code_type, i32 0, i64 %tmp34353637 ; [#uses=1]
+ %tmp39 = load i32* %tmp38, align 4 ; [#uses=1]
+ %tmp40 = icmp eq i32 %tmp39, 2 ; [#uses=4]
+ br i1 %tmp40, label %cond_next46, label %cond_true43
+
+cond_true43: ; preds = %cond_next25
+ tail call void @tree_class_check_failed( %struct.tree_node* %type, i32 2, i8* getelementptr ([28 x i8]* @.str, i32 0, i64 0), i32 1719, i8* getelementptr ([12 x i8]* @__FUNCTION__.22683, i32 0, i32 0) )
+ unreachable
+
+cond_next46: ; preds = %cond_next25
+ %tmp4950 = bitcast %struct.tree_node* %type to %struct.tree_type* ; <%struct.tree_type*> [#uses=2]
+ %tmp51 = getelementptr %struct.tree_type* %tmp4950, i32 0, i32 2 ; <%struct.tree_node**> [#uses=2]
+ %tmp52 = load %struct.tree_node** %tmp51, align 8 ; <%struct.tree_node*> [#uses=1]
+ %tmp53 = icmp eq %struct.tree_node* %tmp52, null ; [#uses=1]
+ br i1 %tmp53, label %cond_next57, label %UnifiedReturnBlock
+
+cond_next57: ; preds = %cond_next46
+ %tmp65 = and i32 %tmp32, 255 ; [#uses=1]
+ switch i32 %tmp65, label %UnifiedReturnBlock [
+ i32 6, label %bb140
+ i32 7, label %bb69
+ i32 8, label %bb140
+ i32 13, label %bb478
+ i32 23, label %bb
+ ]
+
+bb: ; preds = %cond_next57
+ tail call void @fancy_abort( i8* getelementptr ([28 x i8]* @.str, i32 0, i64 0), i32 1727, i8* getelementptr ([12 x i8]* @__FUNCTION__.22683, i32 0, i32 0) )
+ unreachable
+
+bb69: ; preds = %cond_next57
+ br i1 %tmp40, label %cond_next91, label %cond_true88
+
+cond_true88: ; preds = %bb69
+ tail call void @tree_class_check_failed( %struct.tree_node* %type, i32 2, i8* getelementptr ([28 x i8]* @.str, i32 0, i64 0), i32 1730, i8* getelementptr ([12 x i8]* @__FUNCTION__.22683, i32 0, i32 0) )
+ unreachable
+
+cond_next91: ; preds = %bb69
+ %tmp96 = getelementptr %struct.tree_node* %type, i32 0, i32 0, i32 8 ; [#uses=1]
+ %tmp9697 = bitcast i8* %tmp96 to i32* ; [#uses=2]
+ %tmp98 = load i32* %tmp9697, align 8 ; [#uses=2]
+ %tmp100101552 = and i32 %tmp98, 511 ; [#uses=1]
+ %tmp102 = icmp eq i32 %tmp100101552, 0 ; [#uses=1]
+ br i1 %tmp102, label %cond_true105, label %bb140
+
+cond_true105: ; preds = %cond_next91
+ br i1 %tmp40, label %cond_next127, label %cond_true124
+
+cond_true124: ; preds = %cond_true105
+ tail call void @tree_class_check_failed( %struct.tree_node* %type, i32 2, i8* getelementptr ([28 x i8]* @.str, i32 0, i64 0), i32 1731, i8* getelementptr ([12 x i8]* @__FUNCTION__.22683, i32 0, i32 0) )
+ unreachable
+
+cond_next127: ; preds = %cond_true105
+ %tmp136 = or i32 %tmp98, 1 ; [#uses=1]
+ %tmp137 = and i32 %tmp136, -511 ; [#uses=1]
+ store i32 %tmp137, i32* %tmp9697, align 8
+ br label %bb140
+
+bb140: ; preds = %cond_next127, %cond_next91, %cond_next57, %cond_next57
+ switch i8 %tmp3435, label %cond_true202 [
+ i8 6, label %cond_next208
+ i8 9, label %cond_next208
+ i8 7, label %cond_next208
+ i8 8, label %cond_next208
+ i8 10, label %cond_next208
+ ]
+
+cond_true202: ; preds = %bb140
+ tail call void (%struct.tree_node*, i8*, i32, i8*, ...)* @tree_check_failed( %struct.tree_node* %type, i8* getelementptr ([28 x i8]* @.str, i32 0, i64 0), i32 1738, i8* getelementptr ([12 x i8]* @__FUNCTION__.22683, i32 0, i32 0), i32 9, i32 6, i32 7, i32 8, i32 10, i32 0 )
+ unreachable
+
+cond_next208: ; preds = %bb140, %bb140, %bb140, %bb140, %bb140
+ %tmp213 = getelementptr %struct.tree_type* %tmp4950, i32 0, i32 14 ; <%struct.tree_node**> [#uses=1]
+ %tmp214 = load %struct.tree_node** %tmp213, align 8 ; <%struct.tree_node*> [#uses=2]
+ %tmp217 = getelementptr %struct.tree_node* %tmp214, i32 0, i32 0, i32 0, i32 3 ; [#uses=1]
+ %tmp217218 = bitcast i8* %tmp217 to i32* ; [#uses=1]
+ %tmp219 = load i32* %tmp217218, align 8 ; [#uses=1]
+ %tmp221222 = trunc i32 %tmp219 to i8 ; [#uses=1]
+ %tmp223 = icmp eq i8 %tmp221222, 24 ; [#uses=1]
+ br i1 %tmp223, label %cond_true226, label %cond_next340
+
+cond_true226: ; preds = %cond_next208
+ switch i8 %tmp3435, label %cond_true288 [
+ i8 6, label %cond_next294
+ i8 9, label %cond_next294
+ i8 7, label %cond_next294
+ i8 8, label %cond_next294
+ i8 10, label %cond_next294
+ ]
+
+cond_true288: ; preds = %cond_true226
+ tail call void (%struct.tree_node*, i8*, i32, i8*, ...)* @tree_check_failed( %struct.tree_node* %type, i8* getelementptr ([28 x i8]* @.str, i32 0, i64 0), i32 1739, i8* getelementptr ([12 x i8]* @__FUNCTION__.22683, i32 0, i32 0), i32 9, i32 6, i32 7, i32 8, i32 10, i32 0 )
+ unreachable
+
+cond_next294: ; preds = %cond_true226, %cond_true226, %cond_true226, %cond_true226, %cond_true226
+ %tmp301 = tail call i32 @tree_int_cst_sgn( %struct.tree_node* %tmp214 ) ; [#uses=1]
+ %tmp302 = icmp sgt i32 %tmp301, -1 ; [#uses=1]
+ br i1 %tmp302, label %cond_true305, label %cond_next340
+
+cond_true305: ; preds = %cond_next294
+ %tmp313 = load i32* %tmp3031, align 8 ; [#uses=2]
+ %tmp315316 = trunc i32 %tmp313 to i8 ; [#uses=1]
+ %tmp315316317318 = zext i8 %tmp315316 to i64 ; [#uses=1]
+ %tmp319 = getelementptr [0 x i32]* @tree_code_type, i32 0, i64 %tmp315316317318 ; [#uses=1]
+ %tmp320 = load i32* %tmp319, align 4 ; [#uses=1]
+ %tmp321 = icmp eq i32 %tmp320, 2 ; [#uses=1]
+ br i1 %tmp321, label %cond_next327, label %cond_true324
+
+cond_true324: ; preds = %cond_true305
+ tail call void @tree_class_check_failed( %struct.tree_node* %type, i32 2, i8* getelementptr ([28 x i8]* @.str, i32 0, i64 0), i32 1740, i8* getelementptr ([12 x i8]* @__FUNCTION__.22683, i32 0, i32 0) )
+ unreachable
+
+cond_next327: ; preds = %cond_true305
+ %tmp338 = or i32 %tmp313, 8192 ; [#uses=1]
+ store i32 %tmp338, i32* %tmp3031, align 8
+ br label %cond_next340
+
+cond_next340: ; preds = %cond_next327, %cond_next294, %cond_next208
+ %tmp348 = load i32* %tmp3031, align 8 ; [#uses=1]
+ %tmp350351 = trunc i32 %tmp348 to i8 ; [#uses=1]
+ %tmp350351352353 = zext i8 %tmp350351 to i64 ; [#uses=1]
+ %tmp354 = getelementptr [0 x i32]* @tree_code_type, i32 0, i64 %tmp350351352353 ; [#uses=1]
+ %tmp355 = load i32* %tmp354, align 4 ; [#uses=1]
+ %tmp356 = icmp eq i32 %tmp355, 2 ; [#uses=1]
+ br i1 %tmp356, label %cond_next385, label %cond_true359
+
+cond_true359: ; preds = %cond_next340
+ tail call void @tree_class_check_failed( %struct.tree_node* %type, i32 2, i8* getelementptr ([28 x i8]* @.str, i32 0, i64 0), i32 1742, i8* getelementptr ([12 x i8]* @__FUNCTION__.22683, i32 0, i32 0) )
+ unreachable
+
+cond_next385: ; preds = %cond_next340
+ %tmp390 = getelementptr %struct.tree_node* %type, i32 0, i32 0, i32 8 ; [#uses=1]
+ %tmp390391 = bitcast i8* %tmp390 to i32* ; [#uses=3]
+ %tmp392 = load i32* %tmp390391, align 8 ; [#uses=1]
+ %tmp394 = and i32 %tmp392, 511 ; [#uses=1]
+ %tmp397 = tail call i32 @smallest_mode_for_size( i32 %tmp394, i32 2 ) ; [#uses=1]
+ %tmp404 = load i32* %tmp390391, align 8 ; [#uses=1]
+ %tmp397398405 = shl i32 %tmp397, 9 ; [#uses=1]
+ %tmp407 = and i32 %tmp397398405, 65024 ; [#uses=1]
+ %tmp408 = and i32 %tmp404, -65025 ; [#uses=1]
+ %tmp409 = or i32 %tmp408, %tmp407 ; [#uses=2]
+ store i32 %tmp409, i32* %tmp390391, align 8
+ %tmp417 = load i32* %tmp3031, align 8 ; [#uses=1]
+ %tmp419420 = trunc i32 %tmp417 to i8 ; [#uses=1]
+ %tmp419420421422 = zext i8 %tmp419420 to i64 ; [#uses=1]
+ %tmp423 = getelementptr [0 x i32]* @tree_code_type, i32 0, i64 %tmp419420421422 ; [#uses=1]
+ %tmp424 = load i32* %tmp423, align 4 ; [#uses=1]
+ %tmp425 = icmp eq i32 %tmp424, 2 ; [#uses=1]
+ br i1 %tmp425, label %cond_next454, label %cond_true428
+
+cond_true428: ; preds = %cond_next385
+ tail call void @tree_class_check_failed( %struct.tree_node* %type, i32 2, i8* getelementptr ([28 x i8]* @.str, i32 0, i64 0), i32 1744, i8* getelementptr ([12 x i8]* @__FUNCTION__.22683, i32 0, i32 0) )
+ unreachable
+
+cond_next454: ; preds = %cond_next385
+ lshr i32 %tmp409, 9 ; :0 [#uses=1]
+ trunc i32 %0 to i8 ; :1 [#uses=1]
+ %tmp463464 = and i8 %1, 127 ; [#uses=1]
+ %tmp463464465466 = zext i8 %tmp463464 to i64 ; [#uses=1]
+ %tmp467 = getelementptr [48 x i8]* @mode_size, i32 0, i64 %tmp463464465466 ; [#uses=1]
+ %tmp468 = load i8* %tmp467, align 1 ; [#uses=1]
+ %tmp468469553 = zext i8 %tmp468 to i16 ; [#uses=1]
+ %tmp470471 = shl i16 %tmp468469553, 3 ; [#uses=1]
+ %tmp470471472 = zext i16 %tmp470471 to i64 ; [#uses=1]
+ %tmp473 = tail call %struct.tree_node* @size_int_kind( i64 %tmp470471472, i32 2 ) ; <%struct.tree_node*> [#uses=1]
+ store %struct.tree_node* %tmp473, %struct.tree_node** %tmp51, align 8
+ ret void
+
+bb478: ; preds = %cond_next57
+ br i1 %tmp40, label %cond_next500, label %cond_true497
+
+cond_true497: ; preds = %bb478
+ tail call void @tree_class_check_failed( %struct.tree_node* %type, i32 2, i8* getelementptr ([28 x i8]* @.str, i32 0, i64 0), i32 1755, i8* getelementptr ([12 x i8]* @__FUNCTION__.22683, i32 0, i32 0) )
+ unreachable
+
+cond_next500: ; preds = %bb478
+ %tmp506 = getelementptr %struct.tree_node* %type, i32 0, i32 0, i32 0, i32 1 ; <%struct.tree_node**> [#uses=1]
+ %tmp507 = load %struct.tree_node** %tmp506, align 8 ; <%struct.tree_node*> [#uses=2]
+ %tmp511 = getelementptr %struct.tree_node* %tmp507, i32 0, i32 0, i32 0, i32 3 ; [#uses=1]
+ %tmp511512 = bitcast i8* %tmp511 to i32* ; [#uses=1]
+ %tmp513 = load i32* %tmp511512, align 8 ; [#uses=2]
+ %tmp515516 = trunc i32 %tmp513 to i8 ; [#uses=1]
+ %tmp515516517518 = zext i8 %tmp515516 to i64 ; [#uses=1]
+ %tmp519 = getelementptr [0 x i32]* @tree_code_type, i32 0, i64 %tmp515516517518 ; [#uses=1]
+ %tmp520 = load i32* %tmp519, align 4 ; [#uses=1]
+ %tmp521 = icmp eq i32 %tmp520, 2 ; [#uses=1]
+ br i1 %tmp521, label %cond_next527, label %cond_true524
+
+cond_true524: ; preds = %cond_next500
+ tail call void @tree_class_check_failed( %struct.tree_node* %tmp507, i32 2, i8* getelementptr ([28 x i8]* @.str, i32 0, i64 0), i32 1755, i8* getelementptr ([12 x i8]* @__FUNCTION__.22683, i32 0, i32 0) )
+ unreachable
+
+cond_next527: ; preds = %cond_next500
+ %tmp545 = and i32 %tmp513, 8192 ; [#uses=1]
+ %tmp547 = and i32 %tmp32, -8193 ; [#uses=1]
+ %tmp548 = or i32 %tmp547, %tmp545 ; [#uses=1]
+ store i32 %tmp548, i32* %tmp3031, align 8
+ ret void
+
+UnifiedReturnBlock: ; preds = %cond_next57, %cond_next46, %cond_false
+ ret void
+}
+
+declare void @fancy_abort(i8*, i32, i8*)
+
+declare void @tree_class_check_failed(%struct.tree_node*, i32, i8*, i32, i8*)
+
+declare i32 @smallest_mode_for_size(i32, i32)
+
+declare %struct.tree_node* @size_int_kind(i64, i32)
+
+declare void @tree_check_failed(%struct.tree_node*, i8*, i32, i8*, ...)
+
+declare i32 @tree_int_cst_sgn(%struct.tree_node*)
From resistor at mac.com Tue Oct 16 14:59:25 2007
From: resistor at mac.com (Owen Anderson)
Date: Tue, 16 Oct 2007 19:59:25 -0000
Subject: [llvm-commits] [llvm] r43036 - in /llvm/trunk:
include/llvm/Analysis/DominatorInternals.h
include/llvm/Analysis/Dominators.h include/llvm/Analysis/PostDominators.h
lib/Analysis/PostDominators.cpp lib/VMCore/Dominators.cpp
Message-ID: <200710161959.l9GJxQdj013902@zion.cs.uiuc.edu>
Author: resistor
Date: Tue Oct 16 14:59:25 2007
New Revision: 43036
URL: http://llvm.org/viewvc/llvm-project?rev=43036&view=rev
Log:
Template DominatorTreeBase by node type. This is the next major step towards
having dominator information on MBB's.
Modified:
llvm/trunk/include/llvm/Analysis/DominatorInternals.h
llvm/trunk/include/llvm/Analysis/Dominators.h
llvm/trunk/include/llvm/Analysis/PostDominators.h
llvm/trunk/lib/Analysis/PostDominators.cpp
llvm/trunk/lib/VMCore/Dominators.cpp
Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DominatorInternals.h?rev=43036&r1=43035&r2=43036&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/DominatorInternals.h (original)
+++ llvm/trunk/include/llvm/Analysis/DominatorInternals.h Tue Oct 16 14:59:25 2007
@@ -35,8 +35,8 @@
namespace llvm {
template
-unsigned DFSPass(DominatorTreeBase& DT, typename GraphT::NodeType* V,
- unsigned N) {
+unsigned DFSPass(DominatorTreeBase& DT,
+ typename GraphT::NodeType* 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.
@@ -67,7 +67,8 @@
// First time we visited this BB?
if (NextSucc == GraphT::child_begin(BB)) {
- DominatorTree::InfoRec &BBInfo = DT.Info[BB];
+ typename DominatorTreeBase::InfoRec &BBInfo =
+ DT.Info[BB];
BBInfo.Semi = ++N;
BBInfo.Label = BB;
@@ -89,7 +90,8 @@
// Visit the successor next, if it isn't already visited.
typename GraphT::NodeType* Succ = *NextSucc;
- DominatorTree::InfoRec &SuccVInfo = DT.Info[Succ];
+ typename DominatorTreeBase::InfoRec &SuccVInfo =
+ DT.Info[Succ];
if (SuccVInfo.Semi == 0) {
SuccVInfo.Parent = BB;
Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ)));
@@ -100,20 +102,24 @@
}
template
-void Compress(DominatorTreeBase& DT, typename GraphT::NodeType *VIn) {
+void Compress(DominatorTreeBase& DT,
+ typename GraphT::NodeType *VIn) {
std::vector Work;
SmallPtrSet Visited;
typename GraphT::NodeType* VInAncestor = DT.Info[VIn].Ancestor;
- DominatorTreeBase::InfoRec &VInVAInfo = DT.Info[VInAncestor];
+ typename DominatorTreeBase::InfoRec &VInVAInfo =
+ DT.Info[VInAncestor];
if (VInVAInfo.Ancestor != 0)
Work.push_back(VIn);
while (!Work.empty()) {
typename GraphT::NodeType* V = Work.back();
- DominatorTree::InfoRec &VInfo = DT.Info[V];
+ typename DominatorTreeBase::InfoRec &VInfo =
+ DT.Info[V];
typename GraphT::NodeType* VAncestor = VInfo.Ancestor;
- DominatorTreeBase::InfoRec &VAInfo = DT.Info[VAncestor];
+ typename DominatorTreeBase::InfoRec &VAInfo =
+ DT.Info[VAncestor];
// Process Ancestor first
if (Visited.insert(VAncestor) &&
@@ -135,9 +141,10 @@
}
template
-typename GraphT::NodeType* Eval(DominatorTreeBase& DT,
+typename GraphT::NodeType* Eval(DominatorTreeBase& DT,
typename GraphT::NodeType *V) {
- DominatorTreeBase::InfoRec &VInfo = DT.Info[V];
+ typename DominatorTreeBase::InfoRec &VInfo =
+ DT.Info[V];
#if !BALANCE_IDOM_TREE
// Higher-complexity but faster implementation
if (VInfo.Ancestor == 0)
@@ -160,8 +167,9 @@
}
template
-void Link(DominatorTreeBase& DT, typename GraphT::NodeType* V,
- typename GraphT::NodeType* W, DominatorTreeBase::InfoRec &WInfo) {
+void Link(DominatorTreeBase& DT,
+ typename GraphT::NodeType* V, typename GraphT::NodeType* W,
+ typename DominatorTreeBase::InfoRec &WInfo) {
#if !BALANCE_IDOM_TREE
// Higher-complexity but faster implementation
WInfo.Ancestor = V;
@@ -208,49 +216,49 @@
#endif
}
-template
-void Calculate(DominatorTreeBase& DT, Function& F) {
+template
+void Calculate(DominatorTreeBase& DT, Function& F) {
// Step #1: Number blocks in depth-first order and initialize variables used
// in later stages of the algorithm.
unsigned N = 0;
for (unsigned i = 0, e = DT.Roots.size(); i != e; ++i)
- N = DFSPass >(DT, DT.Roots[i], N);
+ N = DFSPass(DT, DT.Roots[i], N);
for (unsigned i = N; i >= 2; --i) {
- typename GraphTraits::NodeType* W = DT.Vertex[i];
- DominatorTree::InfoRec &WInfo = DT.Info[W];
+ typename GraphT::NodeType* W = DT.Vertex[i];
+ typename DominatorTreeBase::InfoRec &WInfo =
+ DT.Info[W];
// Step #2: Calculate the semidominators of all vertices
for (typename GraphTraits >::ChildIteratorType CI =
GraphTraits >::child_begin(W),
E = GraphTraits >::child_end(W); CI != E; ++CI)
if (DT.Info.count(*CI)) { // Only if this predecessor is reachable!
- unsigned SemiU = DT.Info[Eval >(DT, *CI)].Semi;
+ unsigned SemiU = DT.Info[Eval(DT, *CI)].Semi;
if (SemiU < WInfo.Semi)
WInfo.Semi = SemiU;
}
DT.Info[DT.Vertex[WInfo.Semi]].Bucket.push_back(W);
- typename GraphTraits::NodeType* WParent = WInfo.Parent;
- Link >(DT, WParent, W, WInfo);
+ typename GraphT::NodeType* WParent = WInfo.Parent;
+ Link(DT, WParent, W, WInfo);
// Step #3: Implicitly define the immediate dominator of vertices
- std::vector::NodeType*> &WParentBucket =
+ std::vector &WParentBucket =
DT.Info[WParent].Bucket;
while (!WParentBucket.empty()) {
- typename GraphTraits::NodeType* V = WParentBucket.back();
+ typename GraphT::NodeType* V = WParentBucket.back();
WParentBucket.pop_back();
- typename GraphTraits::NodeType* U =
- Eval >(DT, V);
+ typename GraphT::NodeType* U = Eval(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) {
- typename GraphTraits::NodeType* W = DT.Vertex[i];
- typename GraphTraits::NodeType*& WIDom = DT.IDoms[W];
+ typename GraphT::NodeType* W = DT.Vertex[i];
+ typename GraphT::NodeType*& WIDom = DT.IDoms[W];
if (WIDom != DT.Vertex[DT.Info[W].Semi])
WIDom = DT.IDoms[WIDom];
}
@@ -260,13 +268,13 @@
// Add a node for the root. This node might be the actual root, if there is
// one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0)
// which postdominates all real exits if there are multiple exit blocks.
- typename GraphTraits::NodeType* Root = DT.Roots.size() == 1 ? DT.Roots[0]
- : 0;
+ typename GraphT::NodeType* Root = DT.Roots.size() == 1 ? DT.Roots[0]
+ : 0;
DT.DomTreeNodes[Root] = DT.RootNode = new DomTreeNode(Root, 0);
// Loop over all of the reachable blocks in the function...
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
- if (typename GraphTraits::NodeType* ImmDom = DT.getIDom(I)) {
+ if (typename GraphT::NodeType* ImmDom = DT.getIDom(I)) {
// Reachable block.
DomTreeNode *BBNode = DT.DomTreeNodes[I];
if (BBNode) continue; // Haven't calculated this node yet?
@@ -283,7 +291,7 @@
// Free temporary memory used to construct idom's
DT.IDoms.clear();
DT.Info.clear();
- std::vector::NodeType*>().swap(DT.Vertex);
+ std::vector().swap(DT.Vertex);
// FIXME: This does not work on PostDomTrees. It seems likely that this is
// due to an error in the algorithm for post-dominators. This really should
Modified: llvm/trunk/include/llvm/Analysis/Dominators.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=43036&r1=43035&r2=43036&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/Dominators.h (original)
+++ llvm/trunk/include/llvm/Analysis/Dominators.h Tue Oct 16 14:59:25 2007
@@ -22,23 +22,28 @@
#define LLVM_ANALYSIS_DOMINATORS_H
#include "llvm/Pass.h"
+#include "llvm/Instruction.h"
+#include "llvm/Instructions.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Support/Compiler.h"
#include
#include
-#include "llvm/ADT/DenseMap.h"
namespace llvm {
-class Instruction;
-
template struct GraphTraits;
//===----------------------------------------------------------------------===//
/// DominatorBase - Base class that other, more interesting dominator analyses
/// inherit from.
///
+template
class DominatorBase : public FunctionPass {
protected:
- std::vector Roots;
+ std::vector Roots;
const bool IsPostDominators;
inline DominatorBase(intptr_t ID, bool isPostDom) :
FunctionPass(ID), Roots(), IsPostDominators(isPostDom) {}
@@ -48,7 +53,7 @@
/// multiple blocks if we are computing post dominators. For forward
/// dominators, this will always be a single block (the entry node).
///
- inline const std::vector &getRoots() const { return Roots; }
+ inline const std::vector &getRoots() const { return Roots; }
/// isPostDominator - Returns true if analysis based of postdoms
///
@@ -58,7 +63,7 @@
//===----------------------------------------------------------------------===//
// DomTreeNode - Dominator Tree Node
-class DominatorTreeBase;
+template class DominatorTreeBase;
class PostDominatorTree;
class MachineBasicBlock;
@@ -69,7 +74,7 @@
std::vector *> Children;
int DFSNumIn, DFSNumOut;
- friend class DominatorTreeBase;
+ template friend class DominatorTreeBase;
friend class PostDominatorTree;
public:
typedef typename std::vector *>::iterator iterator;
@@ -124,18 +129,43 @@
}
};
+EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase);
+
+template
+static std::ostream &operator<<(std::ostream &o,
+ const DomTreeNodeBase *Node) {
+ if (Node->getBlock())
+ WriteAsOperand(o, Node->getBlock(), false);
+ else
+ o << " <>";
+
+ o << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}";
+
+ return o << "\n";
+}
+
+template
+static void PrintDomTree(const DomTreeNodeBase *N, std::ostream &o,
+ unsigned Lev) {
+ o << std::string(2*Lev, ' ') << "[" << Lev << "] " << N;
+ for (typename DomTreeNodeBase::const_iterator I = N->begin(),
+ E = N->end(); I != E; ++I)
+ PrintDomTree(*I, o, Lev+1);
+}
+
typedef DomTreeNodeBase DomTreeNode;
typedef DomTreeNodeBase MachineDomTreeNode;
//===----------------------------------------------------------------------===//
/// DominatorTree - Calculate the immediate dominator tree for a function.
///
-class DominatorTreeBase : public DominatorBase {
+
+template
+class DominatorTreeBase : public DominatorBase {
protected:
- void reset();
- typedef DenseMap DomTreeNodeMapType;
+ typedef DenseMap*> DomTreeNodeMapType;
DomTreeNodeMapType DomTreeNodes;
- DomTreeNode *RootNode;
+ DomTreeNodeBase *RootNode;
bool DFSInfoValid;
unsigned int SlowQueries;
@@ -143,24 +173,35 @@
struct InfoRec {
unsigned Semi;
unsigned Size;
- BasicBlock *Label, *Parent, *Child, *Ancestor;
+ NodeT *Label, *Parent, *Child, *Ancestor;
- std::vector Bucket;
+ std::vector Bucket;
InfoRec() : Semi(0), Size(0), Label(0), Parent(0), Child(0), Ancestor(0) {}
};
- DenseMap IDoms;
+ DenseMap IDoms;
// Vertex - Map the DFS number to the BasicBlock*
- std::vector Vertex;
+ std::vector Vertex;
// Info - Collection of information used during the computation of idoms.
- DenseMap Info;
+ DenseMap Info;
+
+ void reset() {
+ for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(),
+ E = DomTreeNodes.end(); I != E; ++I)
+ delete I->second;
+ DomTreeNodes.clear();
+ IDoms.clear();
+ this->Roots.clear();
+ Vertex.clear();
+ RootNode = 0;
+ }
public:
DominatorTreeBase(intptr_t ID, bool isPostDom)
- : DominatorBase(ID, isPostDom), DFSInfoValid(false), SlowQueries(0) {}
+ : DominatorBase(ID, isPostDom), DFSInfoValid(false), SlowQueries(0) {}
~DominatorTreeBase() { reset(); }
virtual void releaseMemory() { reset(); }
@@ -168,12 +209,12 @@
/// getNode - return the (Post)DominatorTree node for the specified basic
/// block. This is the same as using operator[] on this class.
///
- inline DomTreeNode *getNode(BasicBlock *BB) const {
- DomTreeNodeMapType::const_iterator I = DomTreeNodes.find(BB);
+ inline DomTreeNodeBase *getNode(NodeT *BB) const {
+ typename DomTreeNodeMapType::const_iterator I = DomTreeNodes.find(BB);
return I != DomTreeNodes.end() ? I->second : 0;
}
- inline DomTreeNode *operator[](BasicBlock *BB) const {
+ inline DomTreeNodeBase *operator[](NodeT *BB) const {
return getNode(BB);
}
@@ -184,25 +225,25 @@
/// post-dominance information must be capable of dealing with this
/// possibility.
///
- DomTreeNode *getRootNode() { return RootNode; }
- const DomTreeNode *getRootNode() const { return RootNode; }
+ DomTreeNodeBase *getRootNode() { return RootNode; }
+ const DomTreeNodeBase *getRootNode() const { return RootNode; }
/// properlyDominates - Returns true iff this dominates N and this != N.
/// Note that this is not a constant time operation!
///
- bool properlyDominates(const DomTreeNode *A,
- DomTreeNode *B) const {
+ bool properlyDominates(const DomTreeNodeBase *A,
+ DomTreeNodeBase *B) const {
if (A == 0 || B == 0) return false;
return dominatedBySlowTreeWalk(A, B);
}
- inline bool properlyDominates(BasicBlock *A, BasicBlock *B) {
+ inline bool properlyDominates(NodeT *A, NodeT *B) {
return properlyDominates(getNode(A), getNode(B));
}
- bool dominatedBySlowTreeWalk(const DomTreeNode *A,
- const DomTreeNode *B) const {
- const DomTreeNode *IDom;
+ bool dominatedBySlowTreeWalk(const DomTreeNodeBase *A,
+ const DomTreeNodeBase *B) const {
+ const DomTreeNodeBase *IDom;
if (A == 0 || B == 0) return false;
while ((IDom = B->getIDom()) != 0 && IDom != A && IDom != B)
B = IDom; // Walk up the tree
@@ -212,13 +253,17 @@
/// isReachableFromEntry - Return true if A is dominated by the entry
/// block of the function containing it.
- const bool isReachableFromEntry(BasicBlock* A);
+ const bool isReachableFromEntry(NodeT* A) {
+ assert (!this->isPostDominator()
+ && "This is not implemented for post dominators");
+ return dominates(&A->getParent()->getEntryBlock(), A);
+ }
/// dominates - Returns true iff A dominates B. Note that this is not a
/// constant time operation!
///
- inline bool dominates(const DomTreeNode *A,
- DomTreeNode *B) {
+ inline bool dominates(const DomTreeNodeBase *A,
+ DomTreeNodeBase *B) {
if (B == A)
return true; // A node trivially dominates itself.
@@ -239,7 +284,7 @@
return dominatedBySlowTreeWalk(A, B);
}
- inline bool dominates(BasicBlock *A, BasicBlock *B) {
+ inline bool dominates(NodeT *A, NodeT *B) {
if (A == B)
return true;
@@ -248,11 +293,73 @@
/// findNearestCommonDominator - Find nearest common dominator basic block
/// for basic block A and B. If there is no such block then return NULL.
- BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B);
+ NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) {
+
+ assert (!this->isPostDominator()
+ && "This is not implemented for post dominators");
+ assert (A->getParent() == B->getParent()
+ && "Two blocks are not in same function");
+
+ // If either A or B is a entry block then it is nearest common dominator.
+ NodeT &Entry = A->getParent()->getEntryBlock();
+ if (A == &Entry || B == &Entry)
+ return &Entry;
+
+ // If B dominates A then B is nearest common dominator.
+ if (dominates(B, A))
+ return B;
+
+ // If A dominates B then A is nearest common dominator.
+ if (dominates(A, B))
+ return A;
+
+ DomTreeNodeBase *NodeA = getNode(A);
+ DomTreeNodeBase *NodeB = getNode(B);
+
+ // Collect NodeA dominators set.
+ SmallPtrSet*, 16> NodeADoms;
+ NodeADoms.insert(NodeA);
+ DomTreeNodeBase *IDomA = NodeA->getIDom();
+ while (IDomA) {
+ NodeADoms.insert(IDomA);
+ IDomA = IDomA->getIDom();
+ }
+
+ // Walk NodeB immediate dominators chain and find common dominator node.
+ DomTreeNodeBase *IDomB = NodeB->getIDom();
+ while(IDomB) {
+ if (NodeADoms.count(IDomB) != 0)
+ return IDomB->getBlock();
+
+ IDomB = IDomB->getIDom();
+ }
+
+ return NULL;
+ }
// dominates - Return true if A dominates B. This performs the
// special checks necessary if A and B are in the same basic block.
- bool dominates(Instruction *A, Instruction *B);
+ bool dominates(Instruction *A, Instruction *B) {
+ NodeT *BBA = A->getParent(), *BBB = B->getParent();
+ if (BBA != BBB) return this->dominates(BBA, BBB);
+
+ // It is not possible to determine dominance between two PHI nodes
+ // based on their ordering.
+ if (isa(A) && isa(B))
+ return false;
+
+ // Loop through the basic block until we find A or B.
+ typename NodeT::iterator I = BBA->begin();
+ for (; &*I != A && &*I != B; ++I) /*empty*/;
+
+ if(!this->IsPostDominators) {
+ // A dominates B if it is found first in the basic block.
+ return &*I == A;
+ } else {
+ // A post-dominates B if B is found first in the basic block.
+ return &*I == B;
+ }
+ }
//===--------------------------------------------------------------------===//
// API to update (Post)DominatorTree information based on modifications to
@@ -261,9 +368,9 @@
/// addNewBlock - Add a new node to the dominator tree information. This
/// creates a new node as a child of DomBB dominator node,linking it into
/// the children list of the immediate dominator.
- DomTreeNode *addNewBlock(BasicBlock *BB, BasicBlock *DomBB) {
+ DomTreeNodeBase *addNewBlock(NodeT *BB, NodeT *DomBB) {
assert(getNode(BB) == 0 && "Block already in dominator tree!");
- DomTreeNode *IDomNode = getNode(DomBB);
+ DomTreeNodeBase *IDomNode = getNode(DomBB);
assert(IDomNode && "Not immediate dominator specified for block!");
DFSInfoValid = false;
return DomTreeNodes[BB] =
@@ -273,76 +380,156 @@
/// changeImmediateDominator - This method is used to update the dominator
/// tree information when a node's immediate dominator changes.
///
- void changeImmediateDominator(DomTreeNode *N,
- DomTreeNode *NewIDom) {
+ void changeImmediateDominator(DomTreeNodeBase *N,
+ DomTreeNodeBase *NewIDom) {
assert(N && NewIDom && "Cannot change null node pointers!");
DFSInfoValid = false;
N->setIDom(NewIDom);
}
- void changeImmediateDominator(BasicBlock *BB, BasicBlock *NewBB) {
+ void changeImmediateDominator(NodeT *BB, NodeT *NewBB) {
changeImmediateDominator(getNode(BB), getNode(NewBB));
}
/// eraseNode - Removes a node from the dominator tree. Block must not
/// domiante any other blocks. Removes node from its immediate dominator's
/// children list. Deletes dominator node associated with basic block BB.
- void eraseNode(BasicBlock *BB);
+ void eraseNode(NodeT *BB) {
+ DomTreeNodeBase *Node = getNode(BB);
+ assert (Node && "Removing node that isn't in dominator tree.");
+ assert (Node->getChildren().empty() && "Node is not a leaf node.");
+
+ // Remove node from immediate dominator's children list.
+ DomTreeNodeBase *IDom = Node->getIDom();
+ if (IDom) {
+ typename std::vector*>::iterator I =
+ std::find(IDom->Children.begin(), IDom->Children.end(), Node);
+ assert(I != IDom->Children.end() &&
+ "Not in immediate dominator children set!");
+ // I am no longer your child...
+ IDom->Children.erase(I);
+ }
+
+ DomTreeNodes.erase(BB);
+ delete Node;
+ }
/// removeNode - Removes a node from the dominator tree. Block must not
/// dominate any other blocks. Invalidates any node pointing to removed
/// block.
- void removeNode(BasicBlock *BB) {
+ void removeNode(NodeT *BB) {
assert(getNode(BB) && "Removing node that isn't in dominator tree.");
DomTreeNodes.erase(BB);
}
/// print - Convert to human readable form
///
- virtual void print(std::ostream &OS, const Module* = 0) const;
+ virtual void print(std::ostream &o, const Module* ) const {
+ o << "=============================--------------------------------\n";
+ o << "Inorder Dominator Tree: ";
+ if (this->DFSInfoValid)
+ o << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
+ o << "\n";
+
+ PrintDomTree(getRootNode(), o, 1);
+ }
+
void print(std::ostream *OS, const Module* M = 0) const {
if (OS) print(*OS, M);
}
- virtual void dump();
+
+ virtual void dump() {
+ print(llvm::cerr);
+ }
protected:
- template friend void Compress(DominatorTreeBase& DT,
+ template friend void Compress(DominatorTreeBase& DT,
typename GraphT::NodeType* VIn);
template friend typename GraphT::NodeType* Eval(
- DominatorTreeBase& DT,
+ DominatorTreeBase& DT,
typename GraphT::NodeType* V);
- template friend void Link(DominatorTreeBase& DT,
+ template friend void Link(DominatorTreeBase& DT,
typename GraphT::NodeType* V,
typename GraphT::NodeType* W,
- InfoRec &WInfo);
+ typename DominatorTreeBase::InfoRec &WInfo);
- template friend unsigned DFSPass(DominatorTreeBase& DT,
+ template friend unsigned DFSPass(
+ DominatorTreeBase& DT,
typename GraphT::NodeType* V,
unsigned N);
- template friend void Calculate(DominatorTreeBase& DT,
- Function& F);
+ template friend void Calculate(DominatorTreeBase& DT,
+ Function& F);
/// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
/// dominator tree in dfs order.
- void updateDFSNumbers();
+ void updateDFSNumbers() {
+ unsigned DFSNum = 0;
+
+ SmallVector*,
+ typename DomTreeNodeBase::iterator>, 32> WorkStack;
+
+ for (unsigned i = 0, e = this->Roots.size(); i != e; ++i) {
+ DomTreeNodeBase *ThisRoot = getNode(this->Roots[i]);
+ WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin()));
+ ThisRoot->DFSNumIn = DFSNum++;
+
+ while (!WorkStack.empty()) {
+ DomTreeNodeBase *Node = WorkStack.back().first;
+ typename DomTreeNodeBase::iterator ChildIt =
+ WorkStack.back().second;
+
+ // If we visited all of the children of this node, "recurse" back up the
+ // stack setting the DFOutNum.
+ if (ChildIt == Node->end()) {
+ Node->DFSNumOut = DFSNum++;
+ WorkStack.pop_back();
+ } else {
+ // Otherwise, recursively visit this child.
+ DomTreeNodeBase *Child = *ChildIt;
+ ++WorkStack.back().second;
+
+ WorkStack.push_back(std::make_pair(Child, Child->begin()));
+ Child->DFSNumIn = DFSNum++;
+ }
+ }
+ }
+
+ SlowQueries = 0;
+ DFSInfoValid = true;
+ }
- DomTreeNode *getNodeForBlock(BasicBlock *BB);
+ DomTreeNodeBase *getNodeForBlock(NodeT *BB) {
+ if (DomTreeNodeBase *BBNode = this->DomTreeNodes[BB])
+ return BBNode;
+
+ // Haven't calculated this node yet? Get or calculate the node for the
+ // immediate dominator.
+ NodeT *IDom = getIDom(BB);
+ DomTreeNodeBase *IDomNode = getNodeForBlock(IDom);
+
+ // Add a new tree node for this BasicBlock, and link it as a child of
+ // IDomNode
+ DomTreeNodeBase *C = new DomTreeNodeBase(BB, IDomNode);
+ return this->DomTreeNodes[BB] = IDomNode->addChild(C);
+ }
- inline BasicBlock *getIDom(BasicBlock *BB) const {
- DenseMap::const_iterator I = IDoms.find(BB);
+ inline NodeT *getIDom(NodeT *BB) const {
+ typename DenseMap::const_iterator I = IDoms.find(BB);
return I != IDoms.end() ? I->second : 0;
}
};
+EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase);
+
//===-------------------------------------
/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
/// compute a normal dominator tree.
///
-class DominatorTree : public DominatorTreeBase {
+class DominatorTree : public DominatorTreeBase {
public:
static char ID; // Pass ID, replacement for typeid
- DominatorTree() : DominatorTreeBase(intptr_t(&ID), false) {}
+ DominatorTree() : DominatorTreeBase(intptr_t(&ID), false) {}
BasicBlock *getRoot() const {
assert(Roots.size() == 1 && "Should always have entry node!");
@@ -392,7 +579,7 @@
/// DominanceFrontierBase - Common base class for computing forward and inverse
/// dominance frontiers for a function.
///
-class DominanceFrontierBase : public DominatorBase {
+class DominanceFrontierBase : public DominatorBase {
public:
typedef std::set DomSetType; // Dom set for a bb
typedef std::map DomSetMapType; // Dom set map
@@ -400,7 +587,7 @@
DomSetMapType Frontiers;
public:
DominanceFrontierBase(intptr_t ID, bool isPostDom)
- : DominatorBase(ID, isPostDom) {}
+ : DominatorBase(ID, isPostDom) {}
virtual void releaseMemory() { Frontiers.clear(); }
Modified: llvm/trunk/include/llvm/Analysis/PostDominators.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PostDominators.h?rev=43036&r1=43035&r2=43036&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/PostDominators.h (original)
+++ llvm/trunk/include/llvm/Analysis/PostDominators.h Tue Oct 16 14:59:25 2007
@@ -21,11 +21,11 @@
/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to
/// compute the a post-dominator tree.
///
-struct PostDominatorTree : public DominatorTreeBase {
+struct PostDominatorTree : public DominatorTreeBase {
static char ID; // Pass identification, replacement for typeid
PostDominatorTree() :
- DominatorTreeBase((intptr_t)&ID, true) {}
+ DominatorTreeBase((intptr_t)&ID, true) {}
virtual bool runOnFunction(Function &F);
Modified: llvm/trunk/lib/Analysis/PostDominators.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PostDominators.cpp?rev=43036&r1=43035&r2=43036&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/PostDominators.cpp (original)
+++ llvm/trunk/lib/Analysis/PostDominators.cpp Tue Oct 16 14:59:25 2007
@@ -47,7 +47,7 @@
Vertex.push_back(0);
- Calculate >(*this, F);
+ Calculate, GraphTraits