Commit 3fa3bcb7 by Ben Clayton

Build: Silence all Clang + SubZero warnings.

Most of these come from LLVM 3. I'd normally try hard to silence these warnings without modifying 3rd party code, but I indend to delete this dependency in the very near future. Bug: b/130343040 Change-Id: Icf6003c58ad118989240d64cf480aa1e2e639fb7 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/29088 Presubmit-Ready: Ben Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com>
parent a0c2bc4c
...@@ -292,6 +292,7 @@ else() ...@@ -292,6 +292,7 @@ else()
set_cpp_flag("-Wno-unneeded-internal-declaration") # function 'X' is not needed and will not be emitted set_cpp_flag("-Wno-unneeded-internal-declaration") # function 'X' is not needed and will not be emitted
set_cpp_flag("-Wno-unused-private-field") # private field 'offset' is not used - TODO: Consider enabling this once Vulkan is further implemented. set_cpp_flag("-Wno-unused-private-field") # private field 'offset' is not used - TODO: Consider enabling this once Vulkan is further implemented.
set_cpp_flag("-Wno-comment") # multi-line comment set_cpp_flag("-Wno-comment") # multi-line comment
set_cpp_flag("-Wno-undefined-var-template") # instantiation of variable 'X' required here, but no definition is available
endif() endif()
# For distribution it is more important to be slim than super optimized # For distribution it is more important to be slim than super optimized
......
...@@ -294,7 +294,6 @@ public: ...@@ -294,7 +294,6 @@ public:
// Loop over the predecessors of the header node... // Loop over the predecessors of the header node...
BlockT *Header = getHeader(); BlockT *Header = getHeader();
typedef GraphTraits<BlockT*> BlockTraits;
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
for (typename InvBlockTraits::ChildIteratorType PI = for (typename InvBlockTraits::ChildIteratorType PI =
InvBlockTraits::child_begin(Header), InvBlockTraits::child_begin(Header),
...@@ -828,10 +827,10 @@ public: ...@@ -828,10 +827,10 @@ public:
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
// Add all of the predecessors of X to the end of the work stack... // Add all of the predecessors of X to the end of the work stack...
for (typename InvBlockTraits::ChildIteratorType PI = InvBlockTraits::child_begin(X), PE = InvBlockTraits::child_end(X); PI != PE; ++PI) { for (typename InvBlockTraits::ChildIteratorType PI = InvBlockTraits::child_begin(X), PE = InvBlockTraits::child_end(X); PI != PE; ++PI) {
typename InvBlockTraits::NodeType *N = *PI; typename InvBlockTraits::NodeType *N = *PI;
TodoStack.push_back(N); TodoStack.push_back(N);
} }
} }
} }
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
namespace llvm { namespace llvm {
class ValueSymbolTable; class ValueSymbolTable;
template<typename NodeTy> class ilist_iterator; template<typename NodeTy> class ilist_iterator;
template<typename NodeTy, typename Traits> class iplist; template<typename NodeTy, typename Traits> class iplist;
template<typename Ty> struct ilist_traits; template<typename Ty> struct ilist_traits;
...@@ -46,7 +46,6 @@ public: ...@@ -46,7 +46,6 @@ public:
/// getListOwner - Return the object that owns this list. If this is a list /// getListOwner - Return the object that owns this list. If this is a list
/// of instructions, it returns the BasicBlock that owns them. /// of instructions, it returns the BasicBlock that owns them.
ItemParentClass *getListOwner() { ItemParentClass *getListOwner() {
typedef iplist<ValueSubClass> ItemParentClass::*Sublist;
size_t Offset(size_t(&((ItemParentClass*)0->*ItemParentClass:: size_t Offset(size_t(&((ItemParentClass*)0->*ItemParentClass::
getSublistAccess(static_cast<ValueSubClass*>(0))))); getSublistAccess(static_cast<ValueSubClass*>(0)))));
iplist<ValueSubClass>* Anchor(static_cast<iplist<ValueSubClass>*>(this)); iplist<ValueSubClass>* Anchor(static_cast<iplist<ValueSubClass>*>(this));
......
...@@ -265,13 +265,6 @@ MachineModuleInfo::MachineModuleInfo(const MCAsmInfo &MAI, ...@@ -265,13 +265,6 @@ MachineModuleInfo::MachineModuleInfo(const MCAsmInfo &MAI,
TheModule = 0; TheModule = 0;
} }
MachineModuleInfo::MachineModuleInfo()
: ImmutablePass(ID),
Context(*(MCAsmInfo*)0, *(MCRegisterInfo*)0, (MCObjectFileInfo*)0) {
assert(0 && "This MachineModuleInfo constructor should never be called, MMI "
"should always be explicitly constructed by LLVMTargetMachine");
abort();
}
MachineModuleInfo::~MachineModuleInfo() { MachineModuleInfo::~MachineModuleInfo() {
delete ObjFileMMI; delete ObjFileMMI;
......
...@@ -1441,7 +1441,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { ...@@ -1441,7 +1441,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
&LoadChains[0], LoadChains.size()); &LoadChains[0], LoadChains.size());
EVT TempWideVector = EVT::getVectorVT(*DAG.getContext(), EVT TempWideVector = EVT::getVectorVT(*DAG.getContext(),
SrcVT.getScalarType(), NumElem*SizeRatio); SrcVT.getScalarType(), NumElem*SizeRatio);
SDValue ValRes = DAG.getNode(ISD::BUILD_VECTOR, dl, SDValue ValRes = DAG.getNode(ISD::BUILD_VECTOR, dl,
TempWideVector, &LoadVals[0], LoadVals.size()); TempWideVector, &LoadVals[0], LoadVals.size());
// Cast to the correct type // Cast to the correct type
...@@ -1629,7 +1629,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { ...@@ -1629,7 +1629,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
break; break;
case TargetLowering::Expand: case TargetLowering::Expand:
EVT WideScalarVT = Tmp3.getValueType().getScalarType();
EVT NarrowScalarVT = StVT.getScalarType(); EVT NarrowScalarVT = StVT.getScalarType();
if (StVT.isVector()) { if (StVT.isVector()) {
...@@ -1649,7 +1648,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { ...@@ -1649,7 +1648,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
if (RegScalarLegal) { if (RegScalarLegal) {
// Cast floats into integers // Cast floats into integers
unsigned ScalarSize = MemSclVT.getSizeInBits(); unsigned ScalarSize = MemSclVT.getSizeInBits();
EVT EltVT = EVT::getIntegerVT(*DAG.getContext(), ScalarSize);
// Round odd types to the next pow of two. // Round odd types to the next pow of two.
if (!isPowerOf2_32(ScalarSize)) if (!isPowerOf2_32(ScalarSize))
......
...@@ -191,17 +191,6 @@ static inline void write_uint32_le(void *Data, uint32_t const &Value) { ...@@ -191,17 +191,6 @@ static inline void write_uint32_le(void *Data, uint32_t const &Value) {
Ptr[3] = (Value & 0xFF000000) >> 24; Ptr[3] = (Value & 0xFF000000) >> 24;
} }
static inline void write_uint16_le(void *Data, uint16_t const &Value) {
uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data);
Ptr[0] = (Value & 0x00FF) >> 0;
Ptr[1] = (Value & 0xFF00) >> 8;
}
static inline void write_uint8_le(void *Data, uint8_t const &Value) {
uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data);
Ptr[0] = (Value & 0xFF) >> 0;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Symbol class implementation // Symbol class implementation
......
...@@ -58,7 +58,7 @@ public: ...@@ -58,7 +58,7 @@ public:
static sys::Mutex gCrashRecoveryContexMutex; static sys::Mutex gCrashRecoveryContexMutex;
static bool gCrashRecoveryEnabled = false; static bool gCrashRecoveryEnabled = false;
static sys::ThreadLocal<const CrashRecoveryContextCleanup> static sys::ThreadLocal<const CrashRecoveryContextCleanup>
tlIsRecoveringFromCrash; tlIsRecoveringFromCrash;
CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {} CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {}
...@@ -75,7 +75,7 @@ CrashRecoveryContext::~CrashRecoveryContext() { ...@@ -75,7 +75,7 @@ CrashRecoveryContext::~CrashRecoveryContext() {
delete tmp; delete tmp;
} }
tlIsRecoveringFromCrash.erase(); tlIsRecoveringFromCrash.erase();
CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl; CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
delete CRCI; delete CRCI;
} }
...@@ -224,10 +224,10 @@ void CrashRecoveryContext::Disable() { ...@@ -224,10 +224,10 @@ void CrashRecoveryContext::Disable() {
#include <signal.h> #include <signal.h>
#ifdef ENABLE_SIGNAL_OVERRIDES
static int Signals[] = { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTRAP }; static int Signals[] = { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTRAP };
static const unsigned NumSignals = sizeof(Signals) / sizeof(Signals[0]); static const unsigned NumSignals = sizeof(Signals) / sizeof(Signals[0]);
static struct sigaction PrevActions[NumSignals]; static struct sigaction PrevActions[NumSignals];
static void CrashRecoverySignalHandler(int Signal) { static void CrashRecoverySignalHandler(int Signal) {
// Lookup the current thread local recovery object. // Lookup the current thread local recovery object.
const CrashRecoveryContextImpl *CRCI = CurrentContext.get(); const CrashRecoveryContextImpl *CRCI = CurrentContext.get();
...@@ -259,6 +259,7 @@ static void CrashRecoverySignalHandler(int Signal) { ...@@ -259,6 +259,7 @@ static void CrashRecoverySignalHandler(int Signal) {
if (CRCI) if (CRCI)
const_cast<CrashRecoveryContextImpl*>(CRCI)->HandleCrash(); const_cast<CrashRecoveryContextImpl*>(CRCI)->HandleCrash();
} }
#endif // ENABLE_SIGNAL_OVERRIDES
void CrashRecoveryContext::Enable() { void CrashRecoveryContext::Enable() {
sys::ScopedLock L(gCrashRecoveryContexMutex); sys::ScopedLock L(gCrashRecoveryContexMutex);
......
...@@ -149,8 +149,10 @@ static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg, ...@@ -149,8 +149,10 @@ static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg,
} }
#endif #endif
#ifdef ENABLE_SIGNAL_OVERRIDES
static void TimeOutHandler(int Sig) { static void TimeOutHandler(int Sig) {
} }
#endif
static void SetMemoryLimits (unsigned size) static void SetMemoryLimits (unsigned size)
{ {
...@@ -302,6 +304,7 @@ Program::Wait(const sys::Path &path, ...@@ -302,6 +304,7 @@ Program::Wait(const sys::Path &path,
{ {
#ifdef HAVE_SYS_WAIT_H #ifdef HAVE_SYS_WAIT_H
struct sigaction Act, Old; struct sigaction Act, Old;
(void)Act; (void)Old;
if (Data_ == 0) { if (Data_ == 0) {
MakeErrMsg(ErrMsg, "Process not started!"); MakeErrMsg(ErrMsg, "Process not started!");
......
...@@ -32,7 +32,9 @@ ...@@ -32,7 +32,9 @@
#endif #endif
using namespace llvm; using namespace llvm;
#ifdef ENABLE_SIGNAL_OVERRIDES
static RETSIGTYPE SignalHandler(int Sig); // defined below. static RETSIGTYPE SignalHandler(int Sig); // defined below.
#endif // ENABLE_SIGNAL_OVERRIDES
static SmartMutex<true> SignalsMutex; static SmartMutex<true> SignalsMutex;
...@@ -76,6 +78,7 @@ static struct { ...@@ -76,6 +78,7 @@ static struct {
} RegisteredSignalInfo[(sizeof(IntSigs)+sizeof(KillSigs))/sizeof(KillSigs[0])]; } RegisteredSignalInfo[(sizeof(IntSigs)+sizeof(KillSigs))/sizeof(KillSigs[0])];
#ifdef ENABLE_SIGNAL_OVERRIDES
static void RegisterHandler(int Signal) { static void RegisterHandler(int Signal) {
assert(NumRegisteredSignals < assert(NumRegisteredSignals <
sizeof(RegisteredSignalInfo)/sizeof(RegisteredSignalInfo[0]) && sizeof(RegisteredSignalInfo)/sizeof(RegisteredSignalInfo[0]) &&
...@@ -93,6 +96,7 @@ static void RegisterHandler(int Signal) { ...@@ -93,6 +96,7 @@ static void RegisterHandler(int Signal) {
RegisteredSignalInfo[NumRegisteredSignals].SigNo = Signal; RegisteredSignalInfo[NumRegisteredSignals].SigNo = Signal;
++NumRegisteredSignals; ++NumRegisteredSignals;
} }
#endif // ENABLE_SIGNAL_OVERRIDES
static void RegisterHandlers() { static void RegisterHandlers() {
#ifdef ENABLE_SIGNAL_OVERRIDES #ifdef ENABLE_SIGNAL_OVERRIDES
...@@ -104,6 +108,7 @@ static void RegisterHandlers() { ...@@ -104,6 +108,7 @@ static void RegisterHandlers() {
#endif #endif
} }
#ifdef ENABLE_SIGNAL_OVERRIDES
static void UnregisterHandlers() { static void UnregisterHandlers() {
// Restore all of the signal handlers to how they were before we showed up. // Restore all of the signal handlers to how they were before we showed up.
for (unsigned i = 0, e = NumRegisteredSignals; i != e; ++i) for (unsigned i = 0, e = NumRegisteredSignals; i != e; ++i)
...@@ -111,6 +116,7 @@ static void UnregisterHandlers() { ...@@ -111,6 +116,7 @@ static void UnregisterHandlers() {
&RegisteredSignalInfo[i].SA, 0); &RegisteredSignalInfo[i].SA, 0);
NumRegisteredSignals = 0; NumRegisteredSignals = 0;
} }
#endif // ENABLE_SIGNAL_OVERRIDES
/// RemoveFilesToRemove - Process the FilesToRemove list. This function /// RemoveFilesToRemove - Process the FilesToRemove list. This function
...@@ -122,6 +128,7 @@ static void RemoveFilesToRemove() { ...@@ -122,6 +128,7 @@ static void RemoveFilesToRemove() {
} }
} }
#ifdef ENABLE_SIGNAL_OVERRIDES
// SignalHandler - The signal handler that runs. // SignalHandler - The signal handler that runs.
static RETSIGTYPE SignalHandler(int Sig) { static RETSIGTYPE SignalHandler(int Sig) {
// Restore the signal behavior to default, so that the program actually // Restore the signal behavior to default, so that the program actually
...@@ -158,6 +165,7 @@ static RETSIGTYPE SignalHandler(int Sig) { ...@@ -158,6 +165,7 @@ static RETSIGTYPE SignalHandler(int Sig) {
for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i) for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i)
CallBacksToRun[i].first(CallBacksToRun[i].second); CallBacksToRun[i].first(CallBacksToRun[i].second);
} }
#endif // ENABLE_SIGNAL_OVERRIDES
void llvm::sys::RunInterruptHandlers() { void llvm::sys::RunInterruptHandlers() {
SignalsMutex.acquire(); SignalsMutex.acquire();
......
...@@ -27,10 +27,10 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) { ...@@ -27,10 +27,10 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
unsigned Opc = FirstInst->getOpcode(); unsigned Opc = FirstInst->getOpcode();
Value *LHSVal = FirstInst->getOperand(0); Value *LHSVal = FirstInst->getOperand(0);
Value *RHSVal = FirstInst->getOperand(1); Value *RHSVal = FirstInst->getOperand(1);
Type *LHSType = LHSVal->getType(); Type *LHSType = LHSVal->getType();
Type *RHSType = RHSVal->getType(); Type *RHSType = RHSVal->getType();
bool isNUW = false, isNSW = false, isExact = false; bool isNUW = false, isNSW = false, isExact = false;
if (OverflowingBinaryOperator *BO = if (OverflowingBinaryOperator *BO =
dyn_cast<OverflowingBinaryOperator>(FirstInst)) { dyn_cast<OverflowingBinaryOperator>(FirstInst)) {
...@@ -39,7 +39,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) { ...@@ -39,7 +39,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
} else if (PossiblyExactOperator *PEO = } else if (PossiblyExactOperator *PEO =
dyn_cast<PossiblyExactOperator>(FirstInst)) dyn_cast<PossiblyExactOperator>(FirstInst))
isExact = PEO->isExact(); isExact = PEO->isExact();
// Scan to see if all operands are the same opcode, and all have one use. // Scan to see if all operands are the same opcode, and all have one use.
for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) { for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
Instruction *I = dyn_cast<Instruction>(PN.getIncomingValue(i)); Instruction *I = dyn_cast<Instruction>(PN.getIncomingValue(i));
...@@ -54,14 +54,14 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) { ...@@ -54,14 +54,14 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
if (CmpInst *CI = dyn_cast<CmpInst>(I)) if (CmpInst *CI = dyn_cast<CmpInst>(I))
if (CI->getPredicate() != cast<CmpInst>(FirstInst)->getPredicate()) if (CI->getPredicate() != cast<CmpInst>(FirstInst)->getPredicate())
return 0; return 0;
if (isNUW) if (isNUW)
isNUW = cast<OverflowingBinaryOperator>(I)->hasNoUnsignedWrap(); isNUW = cast<OverflowingBinaryOperator>(I)->hasNoUnsignedWrap();
if (isNSW) if (isNSW)
isNSW = cast<OverflowingBinaryOperator>(I)->hasNoSignedWrap(); isNSW = cast<OverflowingBinaryOperator>(I)->hasNoSignedWrap();
if (isExact) if (isExact)
isExact = cast<PossiblyExactOperator>(I)->isExact(); isExact = cast<PossiblyExactOperator>(I)->isExact();
// Keep track of which operand needs a phi node. // Keep track of which operand needs a phi node.
if (I->getOperand(0) != LHSVal) LHSVal = 0; if (I->getOperand(0) != LHSVal) LHSVal = 0;
if (I->getOperand(1) != RHSVal) RHSVal = 0; if (I->getOperand(1) != RHSVal) RHSVal = 0;
...@@ -73,9 +73,9 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) { ...@@ -73,9 +73,9 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
// bad when the PHIs are in the header of a loop. // bad when the PHIs are in the header of a loop.
if (!LHSVal && !RHSVal) if (!LHSVal && !RHSVal)
return 0; return 0;
// Otherwise, this is safe to transform! // Otherwise, this is safe to transform!
Value *InLHS = FirstInst->getOperand(0); Value *InLHS = FirstInst->getOperand(0);
Value *InRHS = FirstInst->getOperand(1); Value *InRHS = FirstInst->getOperand(1);
PHINode *NewLHS = 0, *NewRHS = 0; PHINode *NewLHS = 0, *NewRHS = 0;
...@@ -86,7 +86,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) { ...@@ -86,7 +86,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
InsertNewInstBefore(NewLHS, PN); InsertNewInstBefore(NewLHS, PN);
LHSVal = NewLHS; LHSVal = NewLHS;
} }
if (RHSVal == 0) { if (RHSVal == 0) {
NewRHS = PHINode::Create(RHSType, PN.getNumIncomingValues(), NewRHS = PHINode::Create(RHSType, PN.getNumIncomingValues(),
FirstInst->getOperand(1)->getName() + ".pn"); FirstInst->getOperand(1)->getName() + ".pn");
...@@ -94,7 +94,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) { ...@@ -94,7 +94,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
InsertNewInstBefore(NewRHS, PN); InsertNewInstBefore(NewRHS, PN);
RHSVal = NewRHS; RHSVal = NewRHS;
} }
// Add all operands to the new PHIs. // Add all operands to the new PHIs.
if (NewLHS || NewRHS) { if (NewLHS || NewRHS) {
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) { for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
...@@ -109,7 +109,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) { ...@@ -109,7 +109,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
} }
} }
} }
if (CmpInst *CIOp = dyn_cast<CmpInst>(FirstInst)) { if (CmpInst *CIOp = dyn_cast<CmpInst>(FirstInst)) {
CmpInst *NewCI = CmpInst::Create(CIOp->getOpcode(), CIOp->getPredicate(), CmpInst *NewCI = CmpInst::Create(CIOp->getOpcode(), CIOp->getPredicate(),
LHSVal, RHSVal); LHSVal, RHSVal);
...@@ -129,8 +129,8 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) { ...@@ -129,8 +129,8 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) { Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
GetElementPtrInst *FirstInst =cast<GetElementPtrInst>(PN.getIncomingValue(0)); GetElementPtrInst *FirstInst =cast<GetElementPtrInst>(PN.getIncomingValue(0));
SmallVector<Value*, 16> FixedOperands(FirstInst->op_begin(), SmallVector<Value*, 16> FixedOperands(FirstInst->op_begin(),
FirstInst->op_end()); FirstInst->op_end());
// This is true if all GEP bases are allocas and if all indices into them are // This is true if all GEP bases are allocas and if all indices into them are
// constants. // constants.
...@@ -140,9 +140,9 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) { ...@@ -140,9 +140,9 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
// more than one phi, which leads to higher register pressure. This is // more than one phi, which leads to higher register pressure. This is
// especially bad when the PHIs are in the header of a loop. // especially bad when the PHIs are in the header of a loop.
bool NeededPhi = false; bool NeededPhi = false;
bool AllInBounds = true; bool AllInBounds = true;
// Scan to see if all operands are the same opcode, and all have one use. // Scan to see if all operands are the same opcode, and all have one use.
for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) { for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
GetElementPtrInst *GEP= dyn_cast<GetElementPtrInst>(PN.getIncomingValue(i)); GetElementPtrInst *GEP= dyn_cast<GetElementPtrInst>(PN.getIncomingValue(i));
...@@ -151,18 +151,18 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) { ...@@ -151,18 +151,18 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
return 0; return 0;
AllInBounds &= GEP->isInBounds(); AllInBounds &= GEP->isInBounds();
// Keep track of whether or not all GEPs are of alloca pointers. // Keep track of whether or not all GEPs are of alloca pointers.
if (AllBasePointersAreAllocas && if (AllBasePointersAreAllocas &&
(!isa<AllocaInst>(GEP->getOperand(0)) || (!isa<AllocaInst>(GEP->getOperand(0)) ||
!GEP->hasAllConstantIndices())) !GEP->hasAllConstantIndices()))
AllBasePointersAreAllocas = false; AllBasePointersAreAllocas = false;
// Compare the operand lists. // Compare the operand lists.
for (unsigned op = 0, e = FirstInst->getNumOperands(); op != e; ++op) { for (unsigned op = 0, e = FirstInst->getNumOperands(); op != e; ++op) {
if (FirstInst->getOperand(op) == GEP->getOperand(op)) if (FirstInst->getOperand(op) == GEP->getOperand(op))
continue; continue;
// Don't merge two GEPs when two operands differ (introducing phi nodes) // Don't merge two GEPs when two operands differ (introducing phi nodes)
// if one of the PHIs has a constant for the index. The index may be // if one of the PHIs has a constant for the index. The index may be
// substantially cheaper to compute for the constants, so making it a // substantially cheaper to compute for the constants, so making it a
...@@ -171,7 +171,7 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) { ...@@ -171,7 +171,7 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
if (isa<ConstantInt>(FirstInst->getOperand(op)) || if (isa<ConstantInt>(FirstInst->getOperand(op)) ||
isa<ConstantInt>(GEP->getOperand(op))) isa<ConstantInt>(GEP->getOperand(op)))
return 0; return 0;
if (FirstInst->getOperand(op)->getType() !=GEP->getOperand(op)->getType()) if (FirstInst->getOperand(op)->getType() !=GEP->getOperand(op)->getType())
return 0; return 0;
...@@ -186,7 +186,7 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) { ...@@ -186,7 +186,7 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
NeededPhi = true; NeededPhi = true;
} }
} }
// If all of the base pointers of the PHI'd GEPs are from allocas, don't // If all of the base pointers of the PHI'd GEPs are from allocas, don't
// bother doing this transformation. At best, this will just save a bit of // bother doing this transformation. At best, this will just save a bit of
// offset calculation, but all the predecessors will have to materialize the // offset calculation, but all the predecessors will have to materialize the
...@@ -195,11 +195,11 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) { ...@@ -195,11 +195,11 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
// which can usually all be folded into the load. // which can usually all be folded into the load.
if (AllBasePointersAreAllocas) if (AllBasePointersAreAllocas)
return 0; return 0;
// Otherwise, this is safe to transform. Insert PHI nodes for each operand // Otherwise, this is safe to transform. Insert PHI nodes for each operand
// that is variable. // that is variable.
SmallVector<PHINode*, 16> OperandPhis(FixedOperands.size()); SmallVector<PHINode*, 16> OperandPhis(FixedOperands.size());
bool HasAnyPHIs = false; bool HasAnyPHIs = false;
for (unsigned i = 0, e = FixedOperands.size(); i != e; ++i) { for (unsigned i = 0, e = FixedOperands.size(); i != e; ++i) {
if (FixedOperands[i]) continue; // operand doesn't need a phi. if (FixedOperands[i]) continue; // operand doesn't need a phi.
...@@ -207,28 +207,28 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) { ...@@ -207,28 +207,28 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
PHINode *NewPN = PHINode::Create(FirstOp->getType(), e, PHINode *NewPN = PHINode::Create(FirstOp->getType(), e,
FirstOp->getName()+".pn"); FirstOp->getName()+".pn");
InsertNewInstBefore(NewPN, PN); InsertNewInstBefore(NewPN, PN);
NewPN->addIncoming(FirstOp, PN.getIncomingBlock(0)); NewPN->addIncoming(FirstOp, PN.getIncomingBlock(0));
OperandPhis[i] = NewPN; OperandPhis[i] = NewPN;
FixedOperands[i] = NewPN; FixedOperands[i] = NewPN;
HasAnyPHIs = true; HasAnyPHIs = true;
} }
// Add all operands to the new PHIs. // Add all operands to the new PHIs.
if (HasAnyPHIs) { if (HasAnyPHIs) {
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) { for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
GetElementPtrInst *InGEP =cast<GetElementPtrInst>(PN.getIncomingValue(i)); GetElementPtrInst *InGEP =cast<GetElementPtrInst>(PN.getIncomingValue(i));
BasicBlock *InBB = PN.getIncomingBlock(i); BasicBlock *InBB = PN.getIncomingBlock(i);
for (unsigned op = 0, e = OperandPhis.size(); op != e; ++op) for (unsigned op = 0, e = OperandPhis.size(); op != e; ++op)
if (PHINode *OpPhi = OperandPhis[op]) if (PHINode *OpPhi = OperandPhis[op])
OpPhi->addIncoming(InGEP->getOperand(op), InBB); OpPhi->addIncoming(InGEP->getOperand(op), InBB);
} }
} }
Value *Base = FixedOperands[0]; Value *Base = FixedOperands[0];
GetElementPtrInst *NewGEP = GetElementPtrInst *NewGEP =
GetElementPtrInst::Create(Base, makeArrayRef(FixedOperands).slice(1)); GetElementPtrInst::Create(Base, makeArrayRef(FixedOperands).slice(1));
if (AllInBounds) NewGEP->setIsInBounds(); if (AllInBounds) NewGEP->setIsInBounds();
NewGEP->setDebugLoc(FirstInst->getDebugLoc()); NewGEP->setDebugLoc(FirstInst->getDebugLoc());
...@@ -246,11 +246,11 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) { ...@@ -246,11 +246,11 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
/// to a register. /// to a register.
static bool isSafeAndProfitableToSinkLoad(LoadInst *L) { static bool isSafeAndProfitableToSinkLoad(LoadInst *L) {
BasicBlock::iterator BBI = L, E = L->getParent()->end(); BasicBlock::iterator BBI = L, E = L->getParent()->end();
for (++BBI; BBI != E; ++BBI) for (++BBI; BBI != E; ++BBI)
if (BBI->mayWriteToMemory()) if (BBI->mayWriteToMemory())
return false; return false;
// Check for non-address taken alloca. If not address-taken already, it isn't // Check for non-address taken alloca. If not address-taken already, it isn't
// profitable to do this xform. // profitable to do this xform.
if (AllocaInst *AI = dyn_cast<AllocaInst>(L->getOperand(0))) { if (AllocaInst *AI = dyn_cast<AllocaInst>(L->getOperand(0))) {
...@@ -266,11 +266,11 @@ static bool isSafeAndProfitableToSinkLoad(LoadInst *L) { ...@@ -266,11 +266,11 @@ static bool isSafeAndProfitableToSinkLoad(LoadInst *L) {
isAddressTaken = true; isAddressTaken = true;
break; break;
} }
if (!isAddressTaken && AI->isStaticAlloca()) if (!isAddressTaken && AI->isStaticAlloca())
return false; return false;
} }
// If this load is a load from a GEP with a constant offset from an alloca, // If this load is a load from a GEP with a constant offset from an alloca,
// then we don't want to sink it. In its present form, it will be // then we don't want to sink it. In its present form, it will be
// load [constant stack offset]. Sinking it will cause us to have to // load [constant stack offset]. Sinking it will cause us to have to
...@@ -280,7 +280,7 @@ static bool isSafeAndProfitableToSinkLoad(LoadInst *L) { ...@@ -280,7 +280,7 @@ static bool isSafeAndProfitableToSinkLoad(LoadInst *L) {
if (AllocaInst *AI = dyn_cast<AllocaInst>(GEP->getOperand(0))) if (AllocaInst *AI = dyn_cast<AllocaInst>(GEP->getOperand(0)))
if (AI->isStaticAlloca() && GEP->hasAllConstantIndices()) if (AI->isStaticAlloca() && GEP->hasAllConstantIndices())
return false; return false;
return true; return true;
} }
...@@ -300,41 +300,41 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) { ...@@ -300,41 +300,41 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) {
bool isVolatile = FirstLI->isVolatile(); bool isVolatile = FirstLI->isVolatile();
unsigned LoadAlignment = FirstLI->getAlignment(); unsigned LoadAlignment = FirstLI->getAlignment();
unsigned LoadAddrSpace = FirstLI->getPointerAddressSpace(); unsigned LoadAddrSpace = FirstLI->getPointerAddressSpace();
// We can't sink the load if the loaded value could be modified between the // We can't sink the load if the loaded value could be modified between the
// load and the PHI. // load and the PHI.
if (FirstLI->getParent() != PN.getIncomingBlock(0) || if (FirstLI->getParent() != PN.getIncomingBlock(0) ||
!isSafeAndProfitableToSinkLoad(FirstLI)) !isSafeAndProfitableToSinkLoad(FirstLI))
return 0; return 0;
// If the PHI is of volatile loads and the load block has multiple // If the PHI is of volatile loads and the load block has multiple
// successors, sinking it would remove a load of the volatile value from // successors, sinking it would remove a load of the volatile value from
// the path through the other successor. // the path through the other successor.
if (isVolatile && if (isVolatile &&
FirstLI->getParent()->getTerminator()->getNumSuccessors() != 1) FirstLI->getParent()->getTerminator()->getNumSuccessors() != 1)
return 0; return 0;
// Check to see if all arguments are the same operation. // Check to see if all arguments are the same operation.
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) { for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
LoadInst *LI = dyn_cast<LoadInst>(PN.getIncomingValue(i)); LoadInst *LI = dyn_cast<LoadInst>(PN.getIncomingValue(i));
if (!LI || !LI->hasOneUse()) if (!LI || !LI->hasOneUse())
return 0; return 0;
// We can't sink the load if the loaded value could be modified between // We can't sink the load if the loaded value could be modified between
// the load and the PHI. // the load and the PHI.
if (LI->isVolatile() != isVolatile || if (LI->isVolatile() != isVolatile ||
LI->getParent() != PN.getIncomingBlock(i) || LI->getParent() != PN.getIncomingBlock(i) ||
LI->getPointerAddressSpace() != LoadAddrSpace || LI->getPointerAddressSpace() != LoadAddrSpace ||
!isSafeAndProfitableToSinkLoad(LI)) !isSafeAndProfitableToSinkLoad(LI))
return 0; return 0;
// If some of the loads have an alignment specified but not all of them, // If some of the loads have an alignment specified but not all of them,
// we can't do the transformation. // we can't do the transformation.
if ((LoadAlignment != 0) != (LI->getAlignment() != 0)) if ((LoadAlignment != 0) != (LI->getAlignment() != 0))
return 0; return 0;
LoadAlignment = std::min(LoadAlignment, LI->getAlignment()); LoadAlignment = std::min(LoadAlignment, LI->getAlignment());
// If the PHI is of volatile loads and the load block has multiple // If the PHI is of volatile loads and the load block has multiple
// successors, sinking it would remove a load of the volatile value from // successors, sinking it would remove a load of the volatile value from
// the path through the other successor. // the path through the other successor.
...@@ -342,16 +342,16 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) { ...@@ -342,16 +342,16 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) {
LI->getParent()->getTerminator()->getNumSuccessors() != 1) LI->getParent()->getTerminator()->getNumSuccessors() != 1)
return 0; return 0;
} }
// Okay, they are all the same operation. Create a new PHI node of the // Okay, they are all the same operation. Create a new PHI node of the
// correct type, and PHI together all of the LHS's of the instructions. // correct type, and PHI together all of the LHS's of the instructions.
PHINode *NewPN = PHINode::Create(FirstLI->getOperand(0)->getType(), PHINode *NewPN = PHINode::Create(FirstLI->getOperand(0)->getType(),
PN.getNumIncomingValues(), PN.getNumIncomingValues(),
PN.getName()+".in"); PN.getName()+".in");
Value *InVal = FirstLI->getOperand(0); Value *InVal = FirstLI->getOperand(0);
NewPN->addIncoming(InVal, PN.getIncomingBlock(0)); NewPN->addIncoming(InVal, PN.getIncomingBlock(0));
// Add all operands to the new PHI. // Add all operands to the new PHI.
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) { for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
Value *NewInVal = cast<LoadInst>(PN.getIncomingValue(i))->getOperand(0); Value *NewInVal = cast<LoadInst>(PN.getIncomingValue(i))->getOperand(0);
...@@ -359,7 +359,7 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) { ...@@ -359,7 +359,7 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) {
InVal = 0; InVal = 0;
NewPN->addIncoming(NewInVal, PN.getIncomingBlock(i)); NewPN->addIncoming(NewInVal, PN.getIncomingBlock(i));
} }
Value *PhiVal; Value *PhiVal;
if (InVal) { if (InVal) {
// The new PHI unions all of the same values together. This is really // The new PHI unions all of the same values together. This is really
...@@ -370,14 +370,14 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) { ...@@ -370,14 +370,14 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) {
InsertNewInstBefore(NewPN, PN); InsertNewInstBefore(NewPN, PN);
PhiVal = NewPN; PhiVal = NewPN;
} }
// If this was a volatile load that we are merging, make sure to loop through // If this was a volatile load that we are merging, make sure to loop through
// and mark all the input loads as non-volatile. If we don't do this, we will // and mark all the input loads as non-volatile. If we don't do this, we will
// insert a new volatile load and the old ones will not be deletable. // insert a new volatile load and the old ones will not be deletable.
if (isVolatile) if (isVolatile)
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
cast<LoadInst>(PN.getIncomingValue(i))->setVolatile(false); cast<LoadInst>(PN.getIncomingValue(i))->setVolatile(false);
LoadInst *NewLI = new LoadInst(PhiVal, "", isVolatile, LoadAlignment); LoadInst *NewLI = new LoadInst(PhiVal, "", isVolatile, LoadAlignment);
NewLI->setDebugLoc(FirstLI->getDebugLoc()); NewLI->setDebugLoc(FirstLI->getDebugLoc());
return NewLI; return NewLI;
...@@ -395,7 +395,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) { ...@@ -395,7 +395,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
return FoldPHIArgGEPIntoPHI(PN); return FoldPHIArgGEPIntoPHI(PN);
if (isa<LoadInst>(FirstInst)) if (isa<LoadInst>(FirstInst))
return FoldPHIArgLoadIntoPHI(PN); return FoldPHIArgLoadIntoPHI(PN);
// Scan the instruction, looking for input operations that can be folded away. // Scan the instruction, looking for input operations that can be folded away.
// If all input operands to the phi are the same instruction (e.g. a cast from // If all input operands to the phi are the same instruction (e.g. a cast from
// the same type or "+42") we can pull the operation through the PHI, reducing // the same type or "+42") we can pull the operation through the PHI, reducing
...@@ -403,7 +403,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) { ...@@ -403,7 +403,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
Constant *ConstantOp = 0; Constant *ConstantOp = 0;
Type *CastSrcTy = 0; Type *CastSrcTy = 0;
bool isNUW = false, isNSW = false, isExact = false; bool isNUW = false, isNSW = false, isExact = false;
if (isa<CastInst>(FirstInst)) { if (isa<CastInst>(FirstInst)) {
CastSrcTy = FirstInst->getOperand(0)->getType(); CastSrcTy = FirstInst->getOperand(0)->getType();
...@@ -414,12 +414,12 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) { ...@@ -414,12 +414,12 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
return 0; return 0;
} }
} else if (isa<BinaryOperator>(FirstInst) || isa<CmpInst>(FirstInst)) { } else if (isa<BinaryOperator>(FirstInst) || isa<CmpInst>(FirstInst)) {
// Can fold binop, compare or shift here if the RHS is a constant, // Can fold binop, compare or shift here if the RHS is a constant,
// otherwise call FoldPHIArgBinOpIntoPHI. // otherwise call FoldPHIArgBinOpIntoPHI.
ConstantOp = dyn_cast<Constant>(FirstInst->getOperand(1)); ConstantOp = dyn_cast<Constant>(FirstInst->getOperand(1));
if (ConstantOp == 0) if (ConstantOp == 0)
return FoldPHIArgBinOpIntoPHI(PN); return FoldPHIArgBinOpIntoPHI(PN);
if (OverflowingBinaryOperator *BO = if (OverflowingBinaryOperator *BO =
dyn_cast<OverflowingBinaryOperator>(FirstInst)) { dyn_cast<OverflowingBinaryOperator>(FirstInst)) {
isNUW = BO->hasNoUnsignedWrap(); isNUW = BO->hasNoUnsignedWrap();
...@@ -442,7 +442,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) { ...@@ -442,7 +442,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
} else if (I->getOperand(1) != ConstantOp) { } else if (I->getOperand(1) != ConstantOp) {
return 0; return 0;
} }
if (isNUW) if (isNUW)
isNUW = cast<OverflowingBinaryOperator>(I)->hasNoUnsignedWrap(); isNUW = cast<OverflowingBinaryOperator>(I)->hasNoUnsignedWrap();
if (isNSW) if (isNSW)
...@@ -486,7 +486,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) { ...@@ -486,7 +486,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
NewCI->setDebugLoc(FirstInst->getDebugLoc()); NewCI->setDebugLoc(FirstInst->getDebugLoc());
return NewCI; return NewCI;
} }
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst)) { if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst)) {
BinOp = BinaryOperator::Create(BinOp->getOpcode(), PhiVal, ConstantOp); BinOp = BinaryOperator::Create(BinOp->getOpcode(), PhiVal, ConstantOp);
if (isNUW) BinOp->setHasNoUnsignedWrap(); if (isNUW) BinOp->setHasNoUnsignedWrap();
...@@ -495,7 +495,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) { ...@@ -495,7 +495,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
BinOp->setDebugLoc(FirstInst->getDebugLoc()); BinOp->setDebugLoc(FirstInst->getDebugLoc());
return BinOp; return BinOp;
} }
CmpInst *CIOp = cast<CmpInst>(FirstInst); CmpInst *CIOp = cast<CmpInst>(FirstInst);
CmpInst *NewCI = CmpInst::Create(CIOp->getOpcode(), CIOp->getPredicate(), CmpInst *NewCI = CmpInst::Create(CIOp->getOpcode(), CIOp->getPredicate(),
PhiVal, ConstantOp); PhiVal, ConstantOp);
...@@ -513,7 +513,7 @@ static bool DeadPHICycle(PHINode *PN, ...@@ -513,7 +513,7 @@ static bool DeadPHICycle(PHINode *PN,
// Remember this node, and if we find the cycle, return. // Remember this node, and if we find the cycle, return.
if (!PotentiallyDeadPHIs.insert(PN)) if (!PotentiallyDeadPHIs.insert(PN))
return true; return true;
// Don't scan crazily complex things. // Don't scan crazily complex things.
if (PotentiallyDeadPHIs.size() == 16) if (PotentiallyDeadPHIs.size() == 16)
return false; return false;
...@@ -527,16 +527,16 @@ static bool DeadPHICycle(PHINode *PN, ...@@ -527,16 +527,16 @@ static bool DeadPHICycle(PHINode *PN,
/// PHIsEqualValue - Return true if this phi node is always equal to /// PHIsEqualValue - Return true if this phi node is always equal to
/// NonPhiInVal. This happens with mutually cyclic phi nodes like: /// NonPhiInVal. This happens with mutually cyclic phi nodes like:
/// z = some value; x = phi (y, z); y = phi (x, z) /// z = some value; x = phi (y, z); y = phi (x, z)
static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal, static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal,
SmallPtrSet<PHINode*, 16> &ValueEqualPHIs) { SmallPtrSet<PHINode*, 16> &ValueEqualPHIs) {
// See if we already saw this PHI node. // See if we already saw this PHI node.
if (!ValueEqualPHIs.insert(PN)) if (!ValueEqualPHIs.insert(PN))
return true; return true;
// Don't scan crazily complex things. // Don't scan crazily complex things.
if (ValueEqualPHIs.size() == 16) if (ValueEqualPHIs.size() == 16)
return false; return false;
// Scan the operands to see if they are either phi nodes or are equal to // Scan the operands to see if they are either phi nodes or are equal to
// the value. // the value.
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
...@@ -547,7 +547,7 @@ static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal, ...@@ -547,7 +547,7 @@ static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal,
} else if (Op != NonPhiInVal) } else if (Op != NonPhiInVal)
return false; return false;
} }
return true; return true;
} }
...@@ -557,10 +557,10 @@ struct PHIUsageRecord { ...@@ -557,10 +557,10 @@ struct PHIUsageRecord {
unsigned PHIId; // The ID # of the PHI (something determinstic to sort on) unsigned PHIId; // The ID # of the PHI (something determinstic to sort on)
unsigned Shift; // The amount shifted. unsigned Shift; // The amount shifted.
Instruction *Inst; // The trunc instruction. Instruction *Inst; // The trunc instruction.
PHIUsageRecord(unsigned pn, unsigned Sh, Instruction *User) PHIUsageRecord(unsigned pn, unsigned Sh, Instruction *User)
: PHIId(pn), Shift(Sh), Inst(User) {} : PHIId(pn), Shift(Sh), Inst(User) {}
bool operator<(const PHIUsageRecord &RHS) const { bool operator<(const PHIUsageRecord &RHS) const {
if (PHIId < RHS.PHIId) return true; if (PHIId < RHS.PHIId) return true;
if (PHIId > RHS.PHIId) return false; if (PHIId > RHS.PHIId) return false;
...@@ -570,15 +570,15 @@ struct PHIUsageRecord { ...@@ -570,15 +570,15 @@ struct PHIUsageRecord {
RHS.Inst->getType()->getPrimitiveSizeInBits(); RHS.Inst->getType()->getPrimitiveSizeInBits();
} }
}; };
struct LoweredPHIRecord { struct LoweredPHIRecord {
PHINode *PN; // The PHI that was lowered. PHINode *PN; // The PHI that was lowered.
unsigned Shift; // The amount shifted. unsigned Shift; // The amount shifted.
unsigned Width; // The width extracted. unsigned Width; // The width extracted.
LoweredPHIRecord(PHINode *pn, unsigned Sh, Type *Ty) LoweredPHIRecord(PHINode *pn, unsigned Sh, Type *Ty)
: PN(pn), Shift(Sh), Width(Ty->getPrimitiveSizeInBits()) {} : PN(pn), Shift(Sh), Width(Ty->getPrimitiveSizeInBits()) {}
// Ctor form used by DenseMap. // Ctor form used by DenseMap.
LoweredPHIRecord(PHINode *pn, unsigned Sh) LoweredPHIRecord(PHINode *pn, unsigned Sh)
: PN(pn), Shift(Sh), Width(0) {} : PN(pn), Shift(Sh), Width(0) {}
...@@ -608,7 +608,6 @@ namespace llvm { ...@@ -608,7 +608,6 @@ namespace llvm {
struct isPodLike<LoweredPHIRecord> { static const bool value = true; }; struct isPodLike<LoweredPHIRecord> { static const bool value = true; };
} }
/// SliceUpIllegalIntegerPHI - This is an integer PHI and we know that it has an /// SliceUpIllegalIntegerPHI - This is an integer PHI and we know that it has an
/// illegal type: see if it is only used by trunc or trunc(lshr) operations. If /// illegal type: see if it is only used by trunc or trunc(lshr) operations. If
/// so, we split the PHI into the various pieces being extracted. This sort of /// so, we split the PHI into the various pieces being extracted. This sort of
...@@ -618,23 +617,28 @@ namespace llvm { ...@@ -618,23 +617,28 @@ namespace llvm {
/// inttoptr. We should produce new PHIs in the right type. /// inttoptr. We should produce new PHIs in the right type.
/// ///
Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) { Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
// Silence unused variable warning. I'd normally just remove them - but this
// will cause chaos if the compiler is wrong.
(void) isPodLike<LoweredPHIRecord>::value;
// PHIUsers - Keep track of all of the truncated values extracted from a set // PHIUsers - Keep track of all of the truncated values extracted from a set
// of PHIs, along with their offset. These are the things we want to rewrite. // of PHIs, along with their offset. These are the things we want to rewrite.
SmallVector<PHIUsageRecord, 16> PHIUsers; SmallVector<PHIUsageRecord, 16> PHIUsers;
// PHIs are often mutually cyclic, so we keep track of a whole set of PHI // PHIs are often mutually cyclic, so we keep track of a whole set of PHI
// nodes which are extracted from. PHIsToSlice is a set we use to avoid // nodes which are extracted from. PHIsToSlice is a set we use to avoid
// revisiting PHIs, PHIsInspected is a ordered list of PHIs that we need to // revisiting PHIs, PHIsInspected is a ordered list of PHIs that we need to
// check the uses of (to ensure they are all extracts). // check the uses of (to ensure they are all extracts).
SmallVector<PHINode*, 8> PHIsToSlice; SmallVector<PHINode*, 8> PHIsToSlice;
SmallPtrSet<PHINode*, 8> PHIsInspected; SmallPtrSet<PHINode*, 8> PHIsInspected;
PHIsToSlice.push_back(&FirstPhi); PHIsToSlice.push_back(&FirstPhi);
PHIsInspected.insert(&FirstPhi); PHIsInspected.insert(&FirstPhi);
for (unsigned PHIId = 0; PHIId != PHIsToSlice.size(); ++PHIId) { for (unsigned PHIId = 0; PHIId != PHIsToSlice.size(); ++PHIId) {
PHINode *PN = PHIsToSlice[PHIId]; PHINode *PN = PHIsToSlice[PHIId];
// Scan the input list of the PHI. If any input is an invoke, and if the // Scan the input list of the PHI. If any input is an invoke, and if the
// input is defined in the predecessor, then we won't be split the critical // input is defined in the predecessor, then we won't be split the critical
// edge which is required to insert a truncate. Because of this, we have to // edge which is required to insert a truncate. Because of this, we have to
...@@ -644,85 +648,85 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) { ...@@ -644,85 +648,85 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
if (II == 0) continue; if (II == 0) continue;
if (II->getParent() != PN->getIncomingBlock(i)) if (II->getParent() != PN->getIncomingBlock(i))
continue; continue;
// If we have a phi, and if it's directly in the predecessor, then we have // If we have a phi, and if it's directly in the predecessor, then we have
// a critical edge where we need to put the truncate. Since we can't // a critical edge where we need to put the truncate. Since we can't
// split the edge in instcombine, we have to bail out. // split the edge in instcombine, we have to bail out.
return 0; return 0;
} }
for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end(); for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end();
UI != E; ++UI) { UI != E; ++UI) {
Instruction *User = cast<Instruction>(*UI); Instruction *User = cast<Instruction>(*UI);
// If the user is a PHI, inspect its uses recursively. // If the user is a PHI, inspect its uses recursively.
if (PHINode *UserPN = dyn_cast<PHINode>(User)) { if (PHINode *UserPN = dyn_cast<PHINode>(User)) {
if (PHIsInspected.insert(UserPN)) if (PHIsInspected.insert(UserPN))
PHIsToSlice.push_back(UserPN); PHIsToSlice.push_back(UserPN);
continue; continue;
} }
// Truncates are always ok. // Truncates are always ok.
if (isa<TruncInst>(User)) { if (isa<TruncInst>(User)) {
PHIUsers.push_back(PHIUsageRecord(PHIId, 0, User)); PHIUsers.push_back(PHIUsageRecord(PHIId, 0, User));
continue; continue;
} }
// Otherwise it must be a lshr which can only be used by one trunc. // Otherwise it must be a lshr which can only be used by one trunc.
if (User->getOpcode() != Instruction::LShr || if (User->getOpcode() != Instruction::LShr ||
!User->hasOneUse() || !isa<TruncInst>(User->use_back()) || !User->hasOneUse() || !isa<TruncInst>(User->use_back()) ||
!isa<ConstantInt>(User->getOperand(1))) !isa<ConstantInt>(User->getOperand(1)))
return 0; return 0;
unsigned Shift = cast<ConstantInt>(User->getOperand(1))->getZExtValue(); unsigned Shift = cast<ConstantInt>(User->getOperand(1))->getZExtValue();
PHIUsers.push_back(PHIUsageRecord(PHIId, Shift, User->use_back())); PHIUsers.push_back(PHIUsageRecord(PHIId, Shift, User->use_back()));
} }
} }
// If we have no users, they must be all self uses, just nuke the PHI. // If we have no users, they must be all self uses, just nuke the PHI.
if (PHIUsers.empty()) if (PHIUsers.empty())
return ReplaceInstUsesWith(FirstPhi, UndefValue::get(FirstPhi.getType())); return ReplaceInstUsesWith(FirstPhi, UndefValue::get(FirstPhi.getType()));
// If this phi node is transformable, create new PHIs for all the pieces // If this phi node is transformable, create new PHIs for all the pieces
// extracted out of it. First, sort the users by their offset and size. // extracted out of it. First, sort the users by their offset and size.
array_pod_sort(PHIUsers.begin(), PHIUsers.end()); array_pod_sort(PHIUsers.begin(), PHIUsers.end());
DEBUG(errs() << "SLICING UP PHI: " << FirstPhi << '\n'; DEBUG(errs() << "SLICING UP PHI: " << FirstPhi << '\n';
for (unsigned i = 1, e = PHIsToSlice.size(); i != e; ++i) for (unsigned i = 1, e = PHIsToSlice.size(); i != e; ++i)
errs() << "AND USER PHI #" << i << ": " << *PHIsToSlice[i] <<'\n'; errs() << "AND USER PHI #" << i << ": " << *PHIsToSlice[i] <<'\n';
); );
// PredValues - This is a temporary used when rewriting PHI nodes. It is // PredValues - This is a temporary used when rewriting PHI nodes. It is
// hoisted out here to avoid construction/destruction thrashing. // hoisted out here to avoid construction/destruction thrashing.
DenseMap<BasicBlock*, Value*> PredValues; DenseMap<BasicBlock*, Value*> PredValues;
// ExtractedVals - Each new PHI we introduce is saved here so we don't // ExtractedVals - Each new PHI we introduce is saved here so we don't
// introduce redundant PHIs. // introduce redundant PHIs.
DenseMap<LoweredPHIRecord, PHINode*> ExtractedVals; DenseMap<LoweredPHIRecord, PHINode*> ExtractedVals;
for (unsigned UserI = 0, UserE = PHIUsers.size(); UserI != UserE; ++UserI) { for (unsigned UserI = 0, UserE = PHIUsers.size(); UserI != UserE; ++UserI) {
unsigned PHIId = PHIUsers[UserI].PHIId; unsigned PHIId = PHIUsers[UserI].PHIId;
PHINode *PN = PHIsToSlice[PHIId]; PHINode *PN = PHIsToSlice[PHIId];
unsigned Offset = PHIUsers[UserI].Shift; unsigned Offset = PHIUsers[UserI].Shift;
Type *Ty = PHIUsers[UserI].Inst->getType(); Type *Ty = PHIUsers[UserI].Inst->getType();
PHINode *EltPHI; PHINode *EltPHI;
// If we've already lowered a user like this, reuse the previously lowered // If we've already lowered a user like this, reuse the previously lowered
// value. // value.
if ((EltPHI = ExtractedVals[LoweredPHIRecord(PN, Offset, Ty)]) == 0) { if ((EltPHI = ExtractedVals[LoweredPHIRecord(PN, Offset, Ty)]) == 0) {
// Otherwise, Create the new PHI node for this user. // Otherwise, Create the new PHI node for this user.
EltPHI = PHINode::Create(Ty, PN->getNumIncomingValues(), EltPHI = PHINode::Create(Ty, PN->getNumIncomingValues(),
PN->getName()+".off"+Twine(Offset), PN); PN->getName()+".off"+Twine(Offset), PN);
assert(EltPHI->getType() != PN->getType() && assert(EltPHI->getType() != PN->getType() &&
"Truncate didn't shrink phi?"); "Truncate didn't shrink phi?");
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
BasicBlock *Pred = PN->getIncomingBlock(i); BasicBlock *Pred = PN->getIncomingBlock(i);
Value *&PredVal = PredValues[Pred]; Value *&PredVal = PredValues[Pred];
// If we already have a value for this predecessor, reuse it. // If we already have a value for this predecessor, reuse it.
if (PredVal) { if (PredVal) {
EltPHI->addIncoming(PredVal, Pred); EltPHI->addIncoming(PredVal, Pred);
...@@ -736,7 +740,7 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) { ...@@ -736,7 +740,7 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
EltPHI->addIncoming(PredVal, Pred); EltPHI->addIncoming(PredVal, Pred);
continue; continue;
} }
if (PHINode *InPHI = dyn_cast<PHINode>(PN)) { if (PHINode *InPHI = dyn_cast<PHINode>(PN)) {
// If the incoming value was a PHI, and if it was one of the PHIs we // If the incoming value was a PHI, and if it was one of the PHIs we
// already rewrote it, just use the lowered value. // already rewrote it, just use the lowered value.
...@@ -746,7 +750,7 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) { ...@@ -746,7 +750,7 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
continue; continue;
} }
} }
// Otherwise, do an extract in the predecessor. // Otherwise, do an extract in the predecessor.
Builder->SetInsertPoint(Pred, Pred->getTerminator()); Builder->SetInsertPoint(Pred, Pred->getTerminator());
Value *Res = InVal; Value *Res = InVal;
...@@ -756,7 +760,7 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) { ...@@ -756,7 +760,7 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
Res = Builder->CreateTrunc(Res, Ty, "extract.t"); Res = Builder->CreateTrunc(Res, Ty, "extract.t");
PredVal = Res; PredVal = Res;
EltPHI->addIncoming(Res, Pred); EltPHI->addIncoming(Res, Pred);
// If the incoming value was a PHI, and if it was one of the PHIs we are // If the incoming value was a PHI, and if it was one of the PHIs we are
// rewriting, we will ultimately delete the code we inserted. This // rewriting, we will ultimately delete the code we inserted. This
// means we need to revisit that PHI to make sure we extract out the // means we need to revisit that PHI to make sure we extract out the
...@@ -765,22 +769,22 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) { ...@@ -765,22 +769,22 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
if (PHIsInspected.count(OldInVal)) { if (PHIsInspected.count(OldInVal)) {
unsigned RefPHIId = std::find(PHIsToSlice.begin(),PHIsToSlice.end(), unsigned RefPHIId = std::find(PHIsToSlice.begin(),PHIsToSlice.end(),
OldInVal)-PHIsToSlice.begin(); OldInVal)-PHIsToSlice.begin();
PHIUsers.push_back(PHIUsageRecord(RefPHIId, Offset, PHIUsers.push_back(PHIUsageRecord(RefPHIId, Offset,
cast<Instruction>(Res))); cast<Instruction>(Res)));
++UserE; ++UserE;
} }
} }
PredValues.clear(); PredValues.clear();
DEBUG(errs() << " Made element PHI for offset " << Offset << ": " DEBUG(errs() << " Made element PHI for offset " << Offset << ": "
<< *EltPHI << '\n'); << *EltPHI << '\n');
ExtractedVals[LoweredPHIRecord(PN, Offset, Ty)] = EltPHI; ExtractedVals[LoweredPHIRecord(PN, Offset, Ty)] = EltPHI;
} }
// Replace the use of this piece with the PHI node. // Replace the use of this piece with the PHI node.
ReplaceInstUsesWith(*PHIUsers[UserI].Inst, EltPHI); ReplaceInstUsesWith(*PHIUsers[UserI].Inst, EltPHI);
} }
// Replace all the remaining uses of the PHI nodes (self uses and the lshrs) // Replace all the remaining uses of the PHI nodes (self uses and the lshrs)
// with undefs. // with undefs.
Value *Undef = UndefValue::get(FirstPhi.getType()); Value *Undef = UndefValue::get(FirstPhi.getType());
...@@ -818,7 +822,7 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) { ...@@ -818,7 +822,7 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
if (DeadPHICycle(PU, PotentiallyDeadPHIs)) if (DeadPHICycle(PU, PotentiallyDeadPHIs))
return ReplaceInstUsesWith(PN, UndefValue::get(PN.getType())); return ReplaceInstUsesWith(PN, UndefValue::get(PN.getType()));
} }
// If this phi has a single use, and if that use just computes a value for // If this phi has a single use, and if that use just computes a value for
// the next iteration of a loop, delete the phi. This occurs with unused // the next iteration of a loop, delete the phi. This occurs with unused
// induction variables, e.g. "for (int j = 0; ; ++j);". Detecting this // induction variables, e.g. "for (int j = 0; ; ++j);". Detecting this
...@@ -847,7 +851,7 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) { ...@@ -847,7 +851,7 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
if (InValNo != NumIncomingVals) { if (InValNo != NumIncomingVals) {
Value *NonPhiInVal = PN.getIncomingValue(InValNo); Value *NonPhiInVal = PN.getIncomingValue(InValNo);
// Scan the rest of the operands to see if there are any conflicts, if so // Scan the rest of the operands to see if there are any conflicts, if so
// there is no need to recursively scan other phis. // there is no need to recursively scan other phis.
for (++InValNo; InValNo != NumIncomingVals; ++InValNo) { for (++InValNo; InValNo != NumIncomingVals; ++InValNo) {
...@@ -855,7 +859,7 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) { ...@@ -855,7 +859,7 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
if (OpVal != NonPhiInVal && !isa<PHINode>(OpVal)) if (OpVal != NonPhiInVal && !isa<PHINode>(OpVal))
break; break;
} }
// If we scanned over all operands, then we have one unique value plus // If we scanned over all operands, then we have one unique value plus
// phi values. Scan PHI nodes to see if they all merge in each other or // phi values. Scan PHI nodes to see if they all merge in each other or
// the value. // the value.
...@@ -899,6 +903,6 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) { ...@@ -899,6 +903,6 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
!TD->isLegalInteger(PN.getType()->getPrimitiveSizeInBits())) !TD->isLegalInteger(PN.getType()->getPrimitiveSizeInBits()))
if (Instruction *Res = SliceUpIllegalIntegerPHI(PN)) if (Instruction *Res = SliceUpIllegalIntegerPHI(PN))
return Res; return Res;
return 0; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment