From 363eaff04906d61af1f9d67d76a1be3029397c65 Mon Sep 17 00:00:00 2001 From: Tyler Nowicki Date: Tue, 16 Jun 2015 22:59:45 +0000 Subject: [PATCH] Refactor RecurrenceInstDesc Moved RecurrenceInstDesc into RecurrenceDescriptor to simplify the namespaces. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239862 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/Utils/LoopUtils.h | 95 ++++++++++------------ lib/Transforms/Utils/LoopUtils.cpp | 85 ++++++++++--------- lib/Transforms/Vectorize/LoopVectorize.cpp | 2 +- 3 files changed, 87 insertions(+), 95 deletions(-) diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h index 3936f1d5937..15747bc7f1a 100644 --- a/include/llvm/Transforms/Utils/LoopUtils.h +++ b/include/llvm/Transforms/Utils/LoopUtils.h @@ -54,42 +54,6 @@ struct LICMSafetyInfo { /// special case of chains of recurrences (CR). See ScalarEvolution for CR /// references. -/// This POD struct holds information about a potential recurrence operation. -class RecurrenceInstDesc { - -public: - // This enum represents the kind of minmax recurrence. - enum MinMaxRecurrenceKind { - MRK_Invalid, - MRK_UIntMin, - MRK_UIntMax, - MRK_SIntMin, - MRK_SIntMax, - MRK_FloatMin, - MRK_FloatMax - }; - RecurrenceInstDesc(bool IsRecur, Instruction *I) - : IsRecurrence(IsRecur), PatternLastInst(I), MinMaxKind(MRK_Invalid) {} - - RecurrenceInstDesc(Instruction *I, MinMaxRecurrenceKind K) - : IsRecurrence(true), PatternLastInst(I), MinMaxKind(K) {} - - bool isRecurrence() { return IsRecurrence; } - - MinMaxRecurrenceKind getMinMaxKind() { return MinMaxKind; } - - Instruction *getPatternInst() { return PatternLastInst; } - -private: - // Is this instruction a recurrence candidate. - bool IsRecurrence; - // The last instruction in a min/max pattern (select of the select(icmp()) - // pattern), or the current recurrence instruction otherwise. - Instruction *PatternLastInst; - // If this is a min/max pattern the comparison predicate. - MinMaxRecurrenceKind MinMaxKind; -}; - /// This struct holds information about recurrence variables. class RecurrenceDescriptor { @@ -108,23 +72,58 @@ public: RK_FloatMinMax ///< Min/max implemented in terms of select(cmp()). }; + // This enum represents the kind of minmax recurrence. + enum MinMaxRecurrenceKind { + MRK_Invalid, + MRK_UIntMin, + MRK_UIntMax, + MRK_SIntMin, + MRK_SIntMax, + MRK_FloatMin, + MRK_FloatMax + }; + RecurrenceDescriptor() : StartValue(nullptr), LoopExitInstr(nullptr), Kind(RK_NoRecurrence), - MinMaxKind(RecurrenceInstDesc::MRK_Invalid) {} + MinMaxKind(MRK_Invalid) {} RecurrenceDescriptor(Value *Start, Instruction *Exit, RecurrenceKind K, - RecurrenceInstDesc::MinMaxRecurrenceKind MK) + MinMaxRecurrenceKind MK) : StartValue(Start), LoopExitInstr(Exit), Kind(K), MinMaxKind(MK) {} + /// This POD struct holds information about a potential recurrence operation. + class InstDesc { + + public: + InstDesc(bool IsRecur, Instruction *I) + : IsRecurrence(IsRecur), PatternLastInst(I), MinMaxKind(MRK_Invalid) {} + + InstDesc(Instruction *I, MinMaxRecurrenceKind K) + : IsRecurrence(true), PatternLastInst(I), MinMaxKind(K) {} + + bool isRecurrence() { return IsRecurrence; } + + MinMaxRecurrenceKind getMinMaxKind() { return MinMaxKind; } + + Instruction *getPatternInst() { return PatternLastInst; } + + private: + // Is this instruction a recurrence candidate. + bool IsRecurrence; + // The last instruction in a min/max pattern (select of the select(icmp()) + // pattern), or the current recurrence instruction otherwise. + Instruction *PatternLastInst; + // If this is a min/max pattern the comparison predicate. + MinMaxRecurrenceKind MinMaxKind; + }; + /// Returns a struct describing if the instruction 'I' can be a recurrence /// variable of type 'Kind'. If the recurrence is a min/max pattern of /// select(icmp()) this function advances the instruction pointer 'I' from the /// compare instruction to the select instruction and stores this pointer in /// 'PatternLastInst' member of the returned struct. - static RecurrenceInstDesc isRecurrenceInstr(Instruction *I, - RecurrenceKind Kind, - RecurrenceInstDesc &Prev, - bool HasFunNoNaNAttr); + static InstDesc isRecurrenceInstr(Instruction *I, RecurrenceKind Kind, + InstDesc &Prev, bool HasFunNoNaNAttr); /// Returns true if instuction I has multiple uses in Insts static bool hasMultipleUsesOf(Instruction *I, @@ -136,8 +135,7 @@ public: /// Returns a struct describing if the instruction if the instruction is a /// Select(ICmp(X, Y), X, Y) instruction pattern corresponding to a min(X, Y) /// or max(X, Y). - static RecurrenceInstDesc isMinMaxSelectCmpPattern(Instruction *I, - RecurrenceInstDesc &Prev); + static InstDesc isMinMaxSelectCmpPattern(Instruction *I, InstDesc &Prev); /// Returns identity corresponding to the RecurrenceKind. static Constant *getRecurrenceIdentity(RecurrenceKind K, Type *Tp); @@ -147,8 +145,7 @@ public: static unsigned getRecurrenceBinOp(RecurrenceKind Kind); /// Returns a Min/Max operation corresponding to MinMaxRecurrenceKind. - static Value *createMinMaxOp(IRBuilder<> &Builder, - RecurrenceInstDesc::MinMaxRecurrenceKind RK, + static Value *createMinMaxOp(IRBuilder<> &Builder, MinMaxRecurrenceKind RK, Value *Left, Value *Right); /// Returns true if Phi is a reduction of type Kind and adds it to the @@ -164,9 +161,7 @@ public: RecurrenceKind getRecurrenceKind() { return Kind; } - RecurrenceInstDesc::MinMaxRecurrenceKind getMinMaxRecurrenceKind() { - return MinMaxKind; - } + MinMaxRecurrenceKind getMinMaxRecurrenceKind() { return MinMaxKind; } TrackingVH getRecurrenceStartValue() { return StartValue; } @@ -181,7 +176,7 @@ private: // The kind of the recurrence. RecurrenceKind Kind; // If this a min/max recurrence the kind of recurrence. - RecurrenceInstDesc::MinMaxRecurrenceKind MinMaxKind; + MinMaxRecurrenceKind MinMaxKind; }; BasicBlock *InsertPreheaderForLoop(Loop *L, Pass *P); diff --git a/lib/Transforms/Utils/LoopUtils.cpp b/lib/Transforms/Utils/LoopUtils.cpp index c37ecfc881f..5cbde94a98e 100644 --- a/lib/Transforms/Utils/LoopUtils.cpp +++ b/lib/Transforms/Utils/LoopUtils.cpp @@ -66,7 +66,7 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurrenceKind Kind, // the number of instruction we saw from the recognized min/max pattern, // to make sure we only see exactly the two instructions. unsigned NumCmpSelectPatternInst = 0; - RecurrenceInstDesc ReduxDesc(false, nullptr); + InstDesc ReduxDesc(false, nullptr); SmallPtrSet VisitedInsts; SmallVector Worklist; @@ -164,7 +164,7 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurrenceKind Kind, // Process instructions only once (termination). Each reduction cycle // value must only be used once, except by phi nodes and min/max // reductions which are represented as a cmp followed by a select. - RecurrenceInstDesc IgnoredVal(false, nullptr); + InstDesc IgnoredVal(false, nullptr); if (VisitedInsts.insert(UI).second) { if (isa(UI)) PHIs.push_back(UI); @@ -210,9 +210,8 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurrenceKind Kind, /// Returns true if the instruction is a Select(ICmp(X, Y), X, Y) instruction /// pattern corresponding to a min(X, Y) or max(X, Y). -RecurrenceInstDesc -RecurrenceDescriptor::isMinMaxSelectCmpPattern(Instruction *I, - RecurrenceInstDesc &Prev) { +RecurrenceDescriptor::InstDesc +RecurrenceDescriptor::isMinMaxSelectCmpPattern(Instruction *I, InstDesc &Prev) { assert((isa(I) || isa(I) || isa(I)) && "Expect a select instruction"); @@ -223,79 +222,78 @@ RecurrenceDescriptor::isMinMaxSelectCmpPattern(Instruction *I, // select. if ((Cmp = dyn_cast(I)) || (Cmp = dyn_cast(I))) { if (!Cmp->hasOneUse() || !(Select = dyn_cast(*I->user_begin()))) - return RecurrenceInstDesc(false, I); - return RecurrenceInstDesc(Select, Prev.getMinMaxKind()); + return InstDesc(false, I); + return InstDesc(Select, Prev.getMinMaxKind()); } // Only handle single use cases for now. if (!(Select = dyn_cast(I))) - return RecurrenceInstDesc(false, I); + return InstDesc(false, I); if (!(Cmp = dyn_cast(I->getOperand(0))) && !(Cmp = dyn_cast(I->getOperand(0)))) - return RecurrenceInstDesc(false, I); + return InstDesc(false, I); if (!Cmp->hasOneUse()) - return RecurrenceInstDesc(false, I); + return InstDesc(false, I); Value *CmpLeft; Value *CmpRight; // Look for a min/max pattern. if (m_UMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return RecurrenceInstDesc(Select, RecurrenceInstDesc::MRK_UIntMin); + return InstDesc(Select, MRK_UIntMin); else if (m_UMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return RecurrenceInstDesc(Select, RecurrenceInstDesc::MRK_UIntMax); + return InstDesc(Select, MRK_UIntMax); else if (m_SMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return RecurrenceInstDesc(Select, RecurrenceInstDesc::MRK_SIntMax); + return InstDesc(Select, MRK_SIntMax); else if (m_SMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return RecurrenceInstDesc(Select, RecurrenceInstDesc::MRK_SIntMin); + return InstDesc(Select, MRK_SIntMin); else if (m_OrdFMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return RecurrenceInstDesc(Select, RecurrenceInstDesc::MRK_FloatMin); + return InstDesc(Select, MRK_FloatMin); else if (m_OrdFMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return RecurrenceInstDesc(Select, RecurrenceInstDesc::MRK_FloatMax); + return InstDesc(Select, MRK_FloatMax); else if (m_UnordFMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return RecurrenceInstDesc(Select, RecurrenceInstDesc::MRK_FloatMin); + return InstDesc(Select, MRK_FloatMin); else if (m_UnordFMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return RecurrenceInstDesc(Select, RecurrenceInstDesc::MRK_FloatMax); + return InstDesc(Select, MRK_FloatMax); - return RecurrenceInstDesc(false, I); + return InstDesc(false, I); } -RecurrenceInstDesc +RecurrenceDescriptor::InstDesc RecurrenceDescriptor::isRecurrenceInstr(Instruction *I, RecurrenceKind Kind, - RecurrenceInstDesc &Prev, - bool HasFunNoNaNAttr) { + InstDesc &Prev, bool HasFunNoNaNAttr) { bool FP = I->getType()->isFloatingPointTy(); bool FastMath = FP && I->hasUnsafeAlgebra(); switch (I->getOpcode()) { default: - return RecurrenceInstDesc(false, I); + return InstDesc(false, I); case Instruction::PHI: if (FP && (Kind != RK_FloatMult && Kind != RK_FloatAdd && Kind != RK_FloatMinMax)) - return RecurrenceInstDesc(false, I); - return RecurrenceInstDesc(I, Prev.getMinMaxKind()); + return InstDesc(false, I); + return InstDesc(I, Prev.getMinMaxKind()); case Instruction::Sub: case Instruction::Add: - return RecurrenceInstDesc(Kind == RK_IntegerAdd, I); + return InstDesc(Kind == RK_IntegerAdd, I); case Instruction::Mul: - return RecurrenceInstDesc(Kind == RK_IntegerMult, I); + return InstDesc(Kind == RK_IntegerMult, I); case Instruction::And: - return RecurrenceInstDesc(Kind == RK_IntegerAnd, I); + return InstDesc(Kind == RK_IntegerAnd, I); case Instruction::Or: - return RecurrenceInstDesc(Kind == RK_IntegerOr, I); + return InstDesc(Kind == RK_IntegerOr, I); case Instruction::Xor: - return RecurrenceInstDesc(Kind == RK_IntegerXor, I); + return InstDesc(Kind == RK_IntegerXor, I); case Instruction::FMul: - return RecurrenceInstDesc(Kind == RK_FloatMult && FastMath, I); + return InstDesc(Kind == RK_FloatMult && FastMath, I); case Instruction::FSub: case Instruction::FAdd: - return RecurrenceInstDesc(Kind == RK_FloatAdd && FastMath, I); + return InstDesc(Kind == RK_FloatAdd && FastMath, I); case Instruction::FCmp: case Instruction::ICmp: case Instruction::Select: if (Kind != RK_IntegerMinMax && (!HasFunNoNaNAttr || Kind != RK_FloatMinMax)) - return RecurrenceInstDesc(false, I); + return InstDesc(false, I); return isMinMaxSelectCmpPattern(I, Prev); } } @@ -417,36 +415,35 @@ unsigned RecurrenceDescriptor::getRecurrenceBinOp(RecurrenceKind Kind) { } } -Value *RecurrenceDescriptor::createMinMaxOp( - IRBuilder<> &Builder, RecurrenceInstDesc::MinMaxRecurrenceKind RK, - Value *Left, Value *Right) { +Value *RecurrenceDescriptor::createMinMaxOp(IRBuilder<> &Builder, + MinMaxRecurrenceKind RK, + Value *Left, Value *Right) { CmpInst::Predicate P = CmpInst::ICMP_NE; switch (RK) { default: llvm_unreachable("Unknown min/max recurrence kind"); - case RecurrenceInstDesc::MRK_UIntMin: + case MRK_UIntMin: P = CmpInst::ICMP_ULT; break; - case RecurrenceInstDesc::MRK_UIntMax: + case MRK_UIntMax: P = CmpInst::ICMP_UGT; break; - case RecurrenceInstDesc::MRK_SIntMin: + case MRK_SIntMin: P = CmpInst::ICMP_SLT; break; - case RecurrenceInstDesc::MRK_SIntMax: + case MRK_SIntMax: P = CmpInst::ICMP_SGT; break; - case RecurrenceInstDesc::MRK_FloatMin: + case MRK_FloatMin: P = CmpInst::FCMP_OLT; break; - case RecurrenceInstDesc::MRK_FloatMax: + case MRK_FloatMax: P = CmpInst::FCMP_OGT; break; } Value *Cmp; - if (RK == RecurrenceInstDesc::MRK_FloatMin || - RK == RecurrenceInstDesc::MRK_FloatMax) + if (RK == MRK_FloatMin || RK == MRK_FloatMax) Cmp = Builder.CreateFCmp(P, Left, Right, "rdx.minmax.cmp"); else Cmp = Builder.CreateICmp(P, Left, Right, "rdx.minmax.cmp"); diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index 62de2008916..d9a38844b50 100644 --- a/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -3098,7 +3098,7 @@ void InnerLoopVectorizer::vectorizeLoop() { RecurrenceDescriptor::RecurrenceKind RK = RdxDesc.getRecurrenceKind(); TrackingVH ReductionStartValue = RdxDesc.getRecurrenceStartValue(); Instruction *LoopExitInst = RdxDesc.getLoopExitInstr(); - RecurrenceInstDesc::MinMaxRecurrenceKind MinMaxKind = + RecurrenceDescriptor::MinMaxRecurrenceKind MinMaxKind = RdxDesc.getMinMaxRecurrenceKind(); setDebugLocFromInst(Builder, ReductionStartValue);