1 //===------ subzero/src/IcePhiLoweringImpl.h - Phi lowering -----*- C++ -*-===// 2 // 3 // The Subzero Code Generator 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// \brief Utilities for targets to lower Phis. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef SUBZERO_SRC_ICEPHILOWERINGIMPL_H 16 #define SUBZERO_SRC_ICEPHILOWERINGIMPL_H 17 18 #include "IceCfg.h" 19 #include "IceCfgNode.h" 20 #include "IceDefs.h" 21 #include "IceInst.h" 22 #include "IceOperand.h" 23 24 namespace Ice { 25 namespace PhiLowering { 26 27 /// Turn an i64 Phi instruction into a pair of i32 Phi instructions, to preserve 28 /// integrity of liveness analysis. This is needed for 32-bit targets. This 29 /// assumes the 32-bit target has loOperand, hiOperand, and legalizeUndef 30 /// methods. Undef values are also legalized, since loOperand() and hiOperand() 31 /// don't expect Undef input. 32 template <class TargetT> 33 void prelowerPhis32Bit(TargetT *Target, CfgNode *Node, Cfg *Func) { 34 for (Inst &I : Node->getPhis()) { 35 auto *Phi = llvm::dyn_cast<InstPhi>(&I); 36 if (Phi->isDeleted()) 37 continue; 38 Variable *Dest = Phi->getDest(); 39 Type DestTy = Dest->getType(); 40 if (DestTy == IceType_i64) { 41 auto *DestLo = llvm::cast<Variable>(Target->loOperand(Dest)); 42 auto *DestHi = llvm::cast<Variable>(Target->hiOperand(Dest)); 43 auto *PhiLo = InstPhi::create(Func, Phi->getSrcSize(), DestLo); 44 auto *PhiHi = InstPhi::create(Func, Phi->getSrcSize(), DestHi); 45 for (SizeT I = 0; I < Phi->getSrcSize(); ++I) { 46 Operand *Src = Phi->getSrc(I); 47 CfgNode *Label = Phi->getLabel(I); 48 Src = Target->legalizeUndef(Src); 49 PhiLo->addArgument(Target->loOperand(Src), Label); 50 PhiHi->addArgument(Target->hiOperand(Src), Label); 51 } 52 Node->getPhis().push_back(PhiLo); 53 Node->getPhis().push_back(PhiHi); 54 Phi->setDeleted(); 55 } else if (isVectorType(DestTy) && 56 Target->shouldSplitToVariableVecOn32(DestTy)) { 57 auto *DstVec = llvm::cast<VariableVecOn32>(Dest); 58 SizeT Idx = 0; 59 for (Variable *DestElem : DstVec->getContainers()) { 60 auto *PhiElem = InstPhi::create(Func, Phi->getSrcSize(), DestElem); 61 for (SizeT I = 0; I < Phi->getSrcSize(); ++I) { 62 Operand *Src = Phi->getSrc(I); 63 CfgNode *Label = Phi->getLabel(I); 64 Src = Target->legalizeUndef(Src); 65 auto *SrcVec = llvm::cast<VariableVecOn32>(Src); 66 PhiElem->addArgument(SrcVec->getContainers()[Idx], Label); 67 } 68 ++Idx; 69 Node->getPhis().push_back(PhiElem); 70 } 71 Phi->setDeleted(); 72 } 73 } 74 } 75 76 } // end of namespace PhiLowering 77 } // end of namespace Ice 78 79 #endif // SUBZERO_SRC_ICEPHILOWERINGIMPL_H 80