15f757f3fSDimitry Andric //===- VPlanAnalysis.cpp - Various Analyses working on VPlan ----*- C++ -*-===//
25f757f3fSDimitry Andric //
35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f757f3fSDimitry Andric //
75f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
85f757f3fSDimitry Andric
95f757f3fSDimitry Andric #include "VPlanAnalysis.h"
105f757f3fSDimitry Andric #include "VPlan.h"
11*0fca6ea1SDimitry Andric #include "VPlanCFG.h"
125f757f3fSDimitry Andric #include "llvm/ADT/TypeSwitch.h"
13*0fca6ea1SDimitry Andric #include "llvm/IR/Instruction.h"
14*0fca6ea1SDimitry Andric #include "llvm/IR/PatternMatch.h"
155f757f3fSDimitry Andric
165f757f3fSDimitry Andric using namespace llvm;
175f757f3fSDimitry Andric
185f757f3fSDimitry Andric #define DEBUG_TYPE "vplan"
195f757f3fSDimitry Andric
inferScalarTypeForRecipe(const VPBlendRecipe * R)205f757f3fSDimitry Andric Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPBlendRecipe *R) {
215f757f3fSDimitry Andric Type *ResTy = inferScalarType(R->getIncomingValue(0));
225f757f3fSDimitry Andric for (unsigned I = 1, E = R->getNumIncomingValues(); I != E; ++I) {
235f757f3fSDimitry Andric VPValue *Inc = R->getIncomingValue(I);
245f757f3fSDimitry Andric assert(inferScalarType(Inc) == ResTy &&
255f757f3fSDimitry Andric "different types inferred for different incoming values");
265f757f3fSDimitry Andric CachedTypes[Inc] = ResTy;
275f757f3fSDimitry Andric }
285f757f3fSDimitry Andric return ResTy;
295f757f3fSDimitry Andric }
305f757f3fSDimitry Andric
inferScalarTypeForRecipe(const VPInstruction * R)315f757f3fSDimitry Andric Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPInstruction *R) {
32*0fca6ea1SDimitry Andric // Set the result type from the first operand, check if the types for all
33*0fca6ea1SDimitry Andric // other operands match and cache them.
34*0fca6ea1SDimitry Andric auto SetResultTyFromOp = [this, R]() {
35*0fca6ea1SDimitry Andric Type *ResTy = inferScalarType(R->getOperand(0));
36*0fca6ea1SDimitry Andric for (unsigned Op = 1; Op != R->getNumOperands(); ++Op) {
37*0fca6ea1SDimitry Andric VPValue *OtherV = R->getOperand(Op);
38*0fca6ea1SDimitry Andric assert(inferScalarType(OtherV) == ResTy &&
39*0fca6ea1SDimitry Andric "different types inferred for different operands");
40*0fca6ea1SDimitry Andric CachedTypes[OtherV] = ResTy;
41*0fca6ea1SDimitry Andric }
42*0fca6ea1SDimitry Andric return ResTy;
43*0fca6ea1SDimitry Andric };
44*0fca6ea1SDimitry Andric
45*0fca6ea1SDimitry Andric unsigned Opcode = R->getOpcode();
46*0fca6ea1SDimitry Andric if (Instruction::isBinaryOp(Opcode) || Instruction::isUnaryOp(Opcode))
47*0fca6ea1SDimitry Andric return SetResultTyFromOp();
48*0fca6ea1SDimitry Andric
49*0fca6ea1SDimitry Andric switch (Opcode) {
505f757f3fSDimitry Andric case Instruction::Select: {
515f757f3fSDimitry Andric Type *ResTy = inferScalarType(R->getOperand(1));
525f757f3fSDimitry Andric VPValue *OtherV = R->getOperand(2);
535f757f3fSDimitry Andric assert(inferScalarType(OtherV) == ResTy &&
545f757f3fSDimitry Andric "different types inferred for different operands");
555f757f3fSDimitry Andric CachedTypes[OtherV] = ResTy;
565f757f3fSDimitry Andric return ResTy;
575f757f3fSDimitry Andric }
58*0fca6ea1SDimitry Andric case Instruction::ICmp:
59*0fca6ea1SDimitry Andric case VPInstruction::ActiveLaneMask:
60*0fca6ea1SDimitry Andric return inferScalarType(R->getOperand(1));
61*0fca6ea1SDimitry Andric case VPInstruction::FirstOrderRecurrenceSplice:
62*0fca6ea1SDimitry Andric case VPInstruction::Not:
63*0fca6ea1SDimitry Andric return SetResultTyFromOp();
64*0fca6ea1SDimitry Andric case VPInstruction::ExtractFromEnd: {
65*0fca6ea1SDimitry Andric Type *BaseTy = inferScalarType(R->getOperand(0));
66*0fca6ea1SDimitry Andric if (auto *VecTy = dyn_cast<VectorType>(BaseTy))
67*0fca6ea1SDimitry Andric return VecTy->getElementType();
68*0fca6ea1SDimitry Andric return BaseTy;
695f757f3fSDimitry Andric }
70*0fca6ea1SDimitry Andric case VPInstruction::LogicalAnd:
71*0fca6ea1SDimitry Andric return IntegerType::get(Ctx, 1);
72*0fca6ea1SDimitry Andric case VPInstruction::PtrAdd:
73*0fca6ea1SDimitry Andric // Return the type based on the pointer argument (i.e. first operand).
74*0fca6ea1SDimitry Andric return inferScalarType(R->getOperand(0));
75*0fca6ea1SDimitry Andric case VPInstruction::BranchOnCond:
76*0fca6ea1SDimitry Andric case VPInstruction::BranchOnCount:
77*0fca6ea1SDimitry Andric return Type::getVoidTy(Ctx);
785f757f3fSDimitry Andric default:
795f757f3fSDimitry Andric break;
805f757f3fSDimitry Andric }
815f757f3fSDimitry Andric // Type inference not implemented for opcode.
825f757f3fSDimitry Andric LLVM_DEBUG({
835f757f3fSDimitry Andric dbgs() << "LV: Found unhandled opcode for: ";
845f757f3fSDimitry Andric R->getVPSingleValue()->dump();
855f757f3fSDimitry Andric });
865f757f3fSDimitry Andric llvm_unreachable("Unhandled opcode!");
875f757f3fSDimitry Andric }
885f757f3fSDimitry Andric
inferScalarTypeForRecipe(const VPWidenRecipe * R)895f757f3fSDimitry Andric Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenRecipe *R) {
905f757f3fSDimitry Andric unsigned Opcode = R->getOpcode();
915f757f3fSDimitry Andric switch (Opcode) {
925f757f3fSDimitry Andric case Instruction::ICmp:
935f757f3fSDimitry Andric case Instruction::FCmp:
945f757f3fSDimitry Andric return IntegerType::get(Ctx, 1);
955f757f3fSDimitry Andric case Instruction::UDiv:
965f757f3fSDimitry Andric case Instruction::SDiv:
975f757f3fSDimitry Andric case Instruction::SRem:
985f757f3fSDimitry Andric case Instruction::URem:
995f757f3fSDimitry Andric case Instruction::Add:
1005f757f3fSDimitry Andric case Instruction::FAdd:
1015f757f3fSDimitry Andric case Instruction::Sub:
1025f757f3fSDimitry Andric case Instruction::FSub:
1035f757f3fSDimitry Andric case Instruction::Mul:
1045f757f3fSDimitry Andric case Instruction::FMul:
1055f757f3fSDimitry Andric case Instruction::FDiv:
1065f757f3fSDimitry Andric case Instruction::FRem:
1075f757f3fSDimitry Andric case Instruction::Shl:
1085f757f3fSDimitry Andric case Instruction::LShr:
1095f757f3fSDimitry Andric case Instruction::AShr:
1105f757f3fSDimitry Andric case Instruction::And:
1115f757f3fSDimitry Andric case Instruction::Or:
1125f757f3fSDimitry Andric case Instruction::Xor: {
1135f757f3fSDimitry Andric Type *ResTy = inferScalarType(R->getOperand(0));
1145f757f3fSDimitry Andric assert(ResTy == inferScalarType(R->getOperand(1)) &&
1155f757f3fSDimitry Andric "types for both operands must match for binary op");
1165f757f3fSDimitry Andric CachedTypes[R->getOperand(1)] = ResTy;
1175f757f3fSDimitry Andric return ResTy;
1185f757f3fSDimitry Andric }
1195f757f3fSDimitry Andric case Instruction::FNeg:
1205f757f3fSDimitry Andric case Instruction::Freeze:
1215f757f3fSDimitry Andric return inferScalarType(R->getOperand(0));
1225f757f3fSDimitry Andric default:
1235f757f3fSDimitry Andric break;
1245f757f3fSDimitry Andric }
1255f757f3fSDimitry Andric
1265f757f3fSDimitry Andric // Type inference not implemented for opcode.
1275f757f3fSDimitry Andric LLVM_DEBUG({
1285f757f3fSDimitry Andric dbgs() << "LV: Found unhandled opcode for: ";
1295f757f3fSDimitry Andric R->getVPSingleValue()->dump();
1305f757f3fSDimitry Andric });
1315f757f3fSDimitry Andric llvm_unreachable("Unhandled opcode!");
1325f757f3fSDimitry Andric }
1335f757f3fSDimitry Andric
inferScalarTypeForRecipe(const VPWidenCallRecipe * R)1345f757f3fSDimitry Andric Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenCallRecipe *R) {
1355f757f3fSDimitry Andric auto &CI = *cast<CallInst>(R->getUnderlyingInstr());
1365f757f3fSDimitry Andric return CI.getType();
1375f757f3fSDimitry Andric }
1385f757f3fSDimitry Andric
inferScalarTypeForRecipe(const VPWidenMemoryRecipe * R)139*0fca6ea1SDimitry Andric Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenMemoryRecipe *R) {
140*0fca6ea1SDimitry Andric assert((isa<VPWidenLoadRecipe>(R) || isa<VPWidenLoadEVLRecipe>(R)) &&
141*0fca6ea1SDimitry Andric "Store recipes should not define any values");
1425f757f3fSDimitry Andric return cast<LoadInst>(&R->getIngredient())->getType();
1435f757f3fSDimitry Andric }
1445f757f3fSDimitry Andric
inferScalarTypeForRecipe(const VPWidenSelectRecipe * R)1455f757f3fSDimitry Andric Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenSelectRecipe *R) {
1465f757f3fSDimitry Andric Type *ResTy = inferScalarType(R->getOperand(1));
1475f757f3fSDimitry Andric VPValue *OtherV = R->getOperand(2);
1485f757f3fSDimitry Andric assert(inferScalarType(OtherV) == ResTy &&
1495f757f3fSDimitry Andric "different types inferred for different operands");
1505f757f3fSDimitry Andric CachedTypes[OtherV] = ResTy;
1515f757f3fSDimitry Andric return ResTy;
1525f757f3fSDimitry Andric }
1535f757f3fSDimitry Andric
inferScalarTypeForRecipe(const VPReplicateRecipe * R)1545f757f3fSDimitry Andric Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPReplicateRecipe *R) {
1555f757f3fSDimitry Andric switch (R->getUnderlyingInstr()->getOpcode()) {
1565f757f3fSDimitry Andric case Instruction::Call: {
1575f757f3fSDimitry Andric unsigned CallIdx = R->getNumOperands() - (R->isPredicated() ? 2 : 1);
1585f757f3fSDimitry Andric return cast<Function>(R->getOperand(CallIdx)->getLiveInIRValue())
1595f757f3fSDimitry Andric ->getReturnType();
1605f757f3fSDimitry Andric }
1615f757f3fSDimitry Andric case Instruction::UDiv:
1625f757f3fSDimitry Andric case Instruction::SDiv:
1635f757f3fSDimitry Andric case Instruction::SRem:
1645f757f3fSDimitry Andric case Instruction::URem:
1655f757f3fSDimitry Andric case Instruction::Add:
1665f757f3fSDimitry Andric case Instruction::FAdd:
1675f757f3fSDimitry Andric case Instruction::Sub:
1685f757f3fSDimitry Andric case Instruction::FSub:
1695f757f3fSDimitry Andric case Instruction::Mul:
1705f757f3fSDimitry Andric case Instruction::FMul:
1715f757f3fSDimitry Andric case Instruction::FDiv:
1725f757f3fSDimitry Andric case Instruction::FRem:
1735f757f3fSDimitry Andric case Instruction::Shl:
1745f757f3fSDimitry Andric case Instruction::LShr:
1755f757f3fSDimitry Andric case Instruction::AShr:
1765f757f3fSDimitry Andric case Instruction::And:
1775f757f3fSDimitry Andric case Instruction::Or:
1785f757f3fSDimitry Andric case Instruction::Xor: {
1795f757f3fSDimitry Andric Type *ResTy = inferScalarType(R->getOperand(0));
1805f757f3fSDimitry Andric assert(ResTy == inferScalarType(R->getOperand(1)) &&
1815f757f3fSDimitry Andric "inferred types for operands of binary op don't match");
1825f757f3fSDimitry Andric CachedTypes[R->getOperand(1)] = ResTy;
1835f757f3fSDimitry Andric return ResTy;
1845f757f3fSDimitry Andric }
1855f757f3fSDimitry Andric case Instruction::Select: {
1865f757f3fSDimitry Andric Type *ResTy = inferScalarType(R->getOperand(1));
1875f757f3fSDimitry Andric assert(ResTy == inferScalarType(R->getOperand(2)) &&
1885f757f3fSDimitry Andric "inferred types for operands of select op don't match");
1895f757f3fSDimitry Andric CachedTypes[R->getOperand(2)] = ResTy;
1905f757f3fSDimitry Andric return ResTy;
1915f757f3fSDimitry Andric }
1925f757f3fSDimitry Andric case Instruction::ICmp:
1935f757f3fSDimitry Andric case Instruction::FCmp:
1945f757f3fSDimitry Andric return IntegerType::get(Ctx, 1);
195*0fca6ea1SDimitry Andric case Instruction::AddrSpaceCast:
1965f757f3fSDimitry Andric case Instruction::Alloca:
1975f757f3fSDimitry Andric case Instruction::BitCast:
1985f757f3fSDimitry Andric case Instruction::Trunc:
1995f757f3fSDimitry Andric case Instruction::SExt:
2005f757f3fSDimitry Andric case Instruction::ZExt:
2015f757f3fSDimitry Andric case Instruction::FPExt:
2025f757f3fSDimitry Andric case Instruction::FPTrunc:
2035f757f3fSDimitry Andric case Instruction::ExtractValue:
2045f757f3fSDimitry Andric case Instruction::SIToFP:
2055f757f3fSDimitry Andric case Instruction::UIToFP:
2065f757f3fSDimitry Andric case Instruction::FPToSI:
2075f757f3fSDimitry Andric case Instruction::FPToUI:
2085f757f3fSDimitry Andric case Instruction::PtrToInt:
2095f757f3fSDimitry Andric case Instruction::IntToPtr:
2105f757f3fSDimitry Andric return R->getUnderlyingInstr()->getType();
2115f757f3fSDimitry Andric case Instruction::Freeze:
2125f757f3fSDimitry Andric case Instruction::FNeg:
2135f757f3fSDimitry Andric case Instruction::GetElementPtr:
2145f757f3fSDimitry Andric return inferScalarType(R->getOperand(0));
2155f757f3fSDimitry Andric case Instruction::Load:
2165f757f3fSDimitry Andric return cast<LoadInst>(R->getUnderlyingInstr())->getType();
2175f757f3fSDimitry Andric case Instruction::Store:
2185f757f3fSDimitry Andric // FIXME: VPReplicateRecipes with store opcodes still define a result
2195f757f3fSDimitry Andric // VPValue, so we need to handle them here. Remove the code here once this
2205f757f3fSDimitry Andric // is modeled accurately in VPlan.
2215f757f3fSDimitry Andric return Type::getVoidTy(Ctx);
2225f757f3fSDimitry Andric default:
2235f757f3fSDimitry Andric break;
2245f757f3fSDimitry Andric }
2255f757f3fSDimitry Andric // Type inference not implemented for opcode.
2265f757f3fSDimitry Andric LLVM_DEBUG({
2275f757f3fSDimitry Andric dbgs() << "LV: Found unhandled opcode for: ";
2285f757f3fSDimitry Andric R->getVPSingleValue()->dump();
2295f757f3fSDimitry Andric });
2305f757f3fSDimitry Andric llvm_unreachable("Unhandled opcode");
2315f757f3fSDimitry Andric }
2325f757f3fSDimitry Andric
inferScalarType(const VPValue * V)2335f757f3fSDimitry Andric Type *VPTypeAnalysis::inferScalarType(const VPValue *V) {
2345f757f3fSDimitry Andric if (Type *CachedTy = CachedTypes.lookup(V))
2355f757f3fSDimitry Andric return CachedTy;
2365f757f3fSDimitry Andric
237*0fca6ea1SDimitry Andric if (V->isLiveIn()) {
238*0fca6ea1SDimitry Andric if (auto *IRValue = V->getLiveInIRValue())
239*0fca6ea1SDimitry Andric return IRValue->getType();
240*0fca6ea1SDimitry Andric // All VPValues without any underlying IR value (like the vector trip count
241*0fca6ea1SDimitry Andric // or the backedge-taken count) have the same type as the canonical IV.
242*0fca6ea1SDimitry Andric return CanonicalIVTy;
243*0fca6ea1SDimitry Andric }
2445f757f3fSDimitry Andric
2455f757f3fSDimitry Andric Type *ResultTy =
2465f757f3fSDimitry Andric TypeSwitch<const VPRecipeBase *, Type *>(V->getDefiningRecipe())
247*0fca6ea1SDimitry Andric .Case<VPActiveLaneMaskPHIRecipe, VPCanonicalIVPHIRecipe,
248*0fca6ea1SDimitry Andric VPFirstOrderRecurrencePHIRecipe, VPReductionPHIRecipe,
249*0fca6ea1SDimitry Andric VPWidenPointerInductionRecipe, VPEVLBasedIVPHIRecipe>(
2505f757f3fSDimitry Andric [this](const auto *R) {
251*0fca6ea1SDimitry Andric // Handle header phi recipes, except VPWidenIntOrFpInduction
2525f757f3fSDimitry Andric // which needs special handling due it being possibly truncated.
2535f757f3fSDimitry Andric // TODO: consider inferring/caching type of siblings, e.g.,
2545f757f3fSDimitry Andric // backedge value, here and in cases below.
2555f757f3fSDimitry Andric return inferScalarType(R->getStartValue());
2565f757f3fSDimitry Andric })
2575f757f3fSDimitry Andric .Case<VPWidenIntOrFpInductionRecipe, VPDerivedIVRecipe>(
2585f757f3fSDimitry Andric [](const auto *R) { return R->getScalarType(); })
259*0fca6ea1SDimitry Andric .Case<VPReductionRecipe, VPPredInstPHIRecipe, VPWidenPHIRecipe,
260*0fca6ea1SDimitry Andric VPScalarIVStepsRecipe, VPWidenGEPRecipe, VPVectorPointerRecipe,
261*0fca6ea1SDimitry Andric VPWidenCanonicalIVRecipe>([this](const VPRecipeBase *R) {
2625f757f3fSDimitry Andric return inferScalarType(R->getOperand(0));
2635f757f3fSDimitry Andric })
2645f757f3fSDimitry Andric .Case<VPBlendRecipe, VPInstruction, VPWidenRecipe, VPReplicateRecipe,
265*0fca6ea1SDimitry Andric VPWidenCallRecipe, VPWidenMemoryRecipe, VPWidenSelectRecipe>(
2665f757f3fSDimitry Andric [this](const auto *R) { return inferScalarTypeForRecipe(R); })
2675f757f3fSDimitry Andric .Case<VPInterleaveRecipe>([V](const VPInterleaveRecipe *R) {
2685f757f3fSDimitry Andric // TODO: Use info from interleave group.
2695f757f3fSDimitry Andric return V->getUnderlyingValue()->getType();
2705f757f3fSDimitry Andric })
2715f757f3fSDimitry Andric .Case<VPWidenCastRecipe>(
272*0fca6ea1SDimitry Andric [](const VPWidenCastRecipe *R) { return R->getResultType(); })
273*0fca6ea1SDimitry Andric .Case<VPScalarCastRecipe>(
274*0fca6ea1SDimitry Andric [](const VPScalarCastRecipe *R) { return R->getResultType(); })
275*0fca6ea1SDimitry Andric .Case<VPExpandSCEVRecipe>([](const VPExpandSCEVRecipe *R) {
276*0fca6ea1SDimitry Andric return R->getSCEV()->getType();
277*0fca6ea1SDimitry Andric })
278*0fca6ea1SDimitry Andric .Case<VPReductionRecipe>([this](const auto *R) {
279*0fca6ea1SDimitry Andric return inferScalarType(R->getChainOp());
280*0fca6ea1SDimitry Andric });
281*0fca6ea1SDimitry Andric
2825f757f3fSDimitry Andric assert(ResultTy && "could not infer type for the given VPValue");
2835f757f3fSDimitry Andric CachedTypes[V] = ResultTy;
2845f757f3fSDimitry Andric return ResultTy;
2855f757f3fSDimitry Andric }
286*0fca6ea1SDimitry Andric
collectEphemeralRecipesForVPlan(VPlan & Plan,DenseSet<VPRecipeBase * > & EphRecipes)287*0fca6ea1SDimitry Andric void llvm::collectEphemeralRecipesForVPlan(
288*0fca6ea1SDimitry Andric VPlan &Plan, DenseSet<VPRecipeBase *> &EphRecipes) {
289*0fca6ea1SDimitry Andric // First, collect seed recipes which are operands of assumes.
290*0fca6ea1SDimitry Andric SmallVector<VPRecipeBase *> Worklist;
291*0fca6ea1SDimitry Andric for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
292*0fca6ea1SDimitry Andric vp_depth_first_deep(Plan.getVectorLoopRegion()->getEntry()))) {
293*0fca6ea1SDimitry Andric for (VPRecipeBase &R : *VPBB) {
294*0fca6ea1SDimitry Andric auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
295*0fca6ea1SDimitry Andric if (!RepR || !match(RepR->getUnderlyingInstr(),
296*0fca6ea1SDimitry Andric PatternMatch::m_Intrinsic<Intrinsic::assume>()))
297*0fca6ea1SDimitry Andric continue;
298*0fca6ea1SDimitry Andric Worklist.push_back(RepR);
299*0fca6ea1SDimitry Andric EphRecipes.insert(RepR);
300*0fca6ea1SDimitry Andric }
301*0fca6ea1SDimitry Andric }
302*0fca6ea1SDimitry Andric
303*0fca6ea1SDimitry Andric // Process operands of candidates in worklist and add them to the set of
304*0fca6ea1SDimitry Andric // ephemeral recipes, if they don't have side-effects and are only used by
305*0fca6ea1SDimitry Andric // other ephemeral recipes.
306*0fca6ea1SDimitry Andric while (!Worklist.empty()) {
307*0fca6ea1SDimitry Andric VPRecipeBase *Cur = Worklist.pop_back_val();
308*0fca6ea1SDimitry Andric for (VPValue *Op : Cur->operands()) {
309*0fca6ea1SDimitry Andric auto *OpR = Op->getDefiningRecipe();
310*0fca6ea1SDimitry Andric if (!OpR || OpR->mayHaveSideEffects() || EphRecipes.contains(OpR))
311*0fca6ea1SDimitry Andric continue;
312*0fca6ea1SDimitry Andric if (any_of(Op->users(), [EphRecipes](VPUser *U) {
313*0fca6ea1SDimitry Andric auto *UR = dyn_cast<VPRecipeBase>(U);
314*0fca6ea1SDimitry Andric return !UR || !EphRecipes.contains(UR);
315*0fca6ea1SDimitry Andric }))
316*0fca6ea1SDimitry Andric continue;
317*0fca6ea1SDimitry Andric EphRecipes.insert(OpR);
318*0fca6ea1SDimitry Andric Worklist.push_back(OpR);
319*0fca6ea1SDimitry Andric }
320*0fca6ea1SDimitry Andric }
321*0fca6ea1SDimitry Andric }
322