From d1aed7aaf7047873b8878502859905159eaf5362 Mon Sep 17 00:00:00 2001 From: Jim Laskey Date: Thu, 21 Sep 2006 16:28:59 +0000 Subject: [PATCH] Basic "in frame" alias analysis. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30568 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 50 +++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index f093bf46f68..371dd8e5f5b 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -35,6 +35,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/CommandLine.h" #include #include #include @@ -43,8 +44,17 @@ using namespace llvm; namespace { static Statistic<> NodesCombined ("dagcombiner", "Number of dag nodes combined"); + - class VISIBILITY_HIDDEN DAGCombiner { +#ifndef NDEBUG +static cl::opt + CombinerAA("combiner-alias-analysis", cl::Hidden, + cl::desc("Turn on alias analysis turning testing")); +#else + static const bool CombinerAA = 0; +#endif + +class VISIBILITY_HIDDEN DAGCombiner { SelectionDAG &DAG; TargetLowering &TLI; bool AfterLegalize; @@ -231,6 +241,7 @@ namespace { SDOperand BuildSDIV(SDNode *N); SDOperand BuildUDIV(SDNode *N); SDNode *MatchRotate(SDOperand LHS, SDOperand RHS); + bool isNotAlias(SDOperand Ptr1, SDOperand Ptr2); public: DAGCombiner(SelectionDAG &D) : DAG(D), TLI(D.getTargetLoweringInfo()), AfterLegalize(false) {} @@ -2577,6 +2588,27 @@ SDOperand DAGCombiner::visitXEXTLOAD(SDNode *N) { return SDOperand(); } +/// isNotAlias - Return true if we have definitive knowlege that the two +/// addresses don't overlap. +bool DAGCombiner::isNotAlias(SDOperand Ptr1, SDOperand Ptr2) { + // Mind the flag. + if (!CombinerAA) return false; + + // If they are the same then they are simple aliases. + if (Ptr1 == Ptr2) return false; + + // If either operand is a frame value (not the same location from above test) + // then they can't alias. + FrameIndexSDNode *FI1 = dyn_cast(Ptr1); + FrameIndexSDNode *FI2 = dyn_cast(Ptr2); + if (FI1 || FI2) { + return true; + } + + // Otherwise we don't know and have to play it safe. + return false; +} + SDOperand DAGCombiner::visitSTORE(SDNode *N) { SDOperand Chain = N->getOperand(0); SDOperand Value = N->getOperand(1); @@ -2607,6 +2639,22 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) { if (0 && Value.getOpcode() == ISD::BIT_CONVERT) return DAG.getNode(ISD::STORE, MVT::Other, Chain, Value.getOperand(0), Ptr, SrcValue); + + // If the previous store is not an alias then break artificial chain. + if (Chain.getOpcode() == ISD::STORE && isNotAlias(Ptr, Chain.getOperand(2))) { + // Replace the chain to void dependency. + SDNode *PrevStore = Chain.Val; + SDOperand ReplStore = DAG.getNode(ISD::STORE, MVT::Other, + PrevStore->getOperand(0), Value, Ptr, + SrcValue); + // Create token to keep both stores around. + SDOperand Token = DAG.getNode(ISD::TokenFactor, MVT::Other, + Chain, ReplStore); + // Replace uses with token. + CombineTo(N, Token); + // Don't recombine on token. + return SDOperand(N, 0); + } return SDOperand(); }