Index: llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h =================================================================== --- llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -74,14 +74,24 @@ /// This is the base class for unary cast operator classes. class SCEVCastExpr : public SCEV { protected: - const SCEV *Op; + std::array Operands; Type *Ty; SCEVCastExpr(const FoldingSetNodeIDRef ID, unsigned SCEVTy, const SCEV *op, Type *ty); public: - const SCEV *getOperand() const { return Op; } + const SCEV *getOperand() const { return Operands[0]; } + const SCEV *getOperand(unsigned i) const { + assert(i == 0 && "Operand index out of range!"); + return Operands[0]; + } + using op_iterator = const SCEV *const *; + using op_range = iterator_range; + op_range operands() const { + return make_range(Operands.begin(), Operands.end()); + } + size_t getNumOperands() const { return 1; } Type *getType() const { return Ty; } /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -263,16 +273,30 @@ class SCEVUDivExpr : public SCEV { friend class ScalarEvolution; - const SCEV *LHS; - const SCEV *RHS; + std::array Operands; SCEVUDivExpr(const FoldingSetNodeIDRef ID, const SCEV *lhs, const SCEV *rhs) - : SCEV(ID, scUDivExpr, computeExpressionSize({lhs, rhs})), LHS(lhs), - RHS(rhs) {} + : SCEV(ID, scUDivExpr, computeExpressionSize({lhs, rhs})) { + Operands[0] = lhs; + Operands[1] = rhs; + } public: - const SCEV *getLHS() const { return LHS; } - const SCEV *getRHS() const { return RHS; } + const SCEV *getLHS() const { return Operands[0]; } + const SCEV *getRHS() const { return Operands[1]; } + size_t getNumOperands() const { return 2; } + const SCEV *getOperand(unsigned i) const { + assert((i == 0 || i == 1) && "Operand index out of range!"); + return i == 0 ? getLHS() : getRHS(); + } + using op_iterator = const SCEV *const *; + using op_range = iterator_range; + + op_iterator op_begin() const { return &Operands[0]; } + op_iterator op_end() const { return &Operands[1]; } + op_range operands() const { + return make_range(op_begin(), op_end()); + } Type *getType() const { // In most cases the types of LHS and RHS will be the same, but in some Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -447,26 +447,28 @@ SCEVCastExpr::SCEVCastExpr(const FoldingSetNodeIDRef ID, unsigned SCEVTy, const SCEV *op, Type *ty) - : SCEV(ID, SCEVTy, computeExpressionSize(op)), Op(op), Ty(ty) {} + : SCEV(ID, SCEVTy, computeExpressionSize(op)), Ty(ty) { + Operands[0] = op; + } SCEVTruncateExpr::SCEVTruncateExpr(const FoldingSetNodeIDRef ID, const SCEV *op, Type *ty) : SCEVCastExpr(ID, scTruncate, op, ty) { - assert(Op->getType()->isIntOrPtrTy() && Ty->isIntOrPtrTy() && + assert(Operands[0]->getType()->isIntOrPtrTy() && Ty->isIntOrPtrTy() && "Cannot truncate non-integer value!"); } SCEVZeroExtendExpr::SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID, const SCEV *op, Type *ty) : SCEVCastExpr(ID, scZeroExtend, op, ty) { - assert(Op->getType()->isIntOrPtrTy() && Ty->isIntOrPtrTy() && + assert(Operands[0]->getType()->isIntOrPtrTy() && Ty->isIntOrPtrTy() && "Cannot zero extend non-integer value!"); } SCEVSignExtendExpr::SCEVSignExtendExpr(const FoldingSetNodeIDRef ID, const SCEV *op, Type *ty) : SCEVCastExpr(ID, scSignExtend, op, ty) { - assert(Op->getType()->isIntOrPtrTy() && Ty->isIntOrPtrTy() && + assert(Operands[0]->getType()->isIntOrPtrTy() && Ty->isIntOrPtrTy() && "Cannot sign extend non-integer value!"); }