|  | //===------ subzero/src/IcePhiLoweringImpl.h - Phi lowering -----*- C++ -*-===// | 
|  | // | 
|  | //                        The Subzero Code Generator | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | /// | 
|  | /// \file | 
|  | /// \brief Utilities for targets to lower Phis. | 
|  | /// | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef SUBZERO_SRC_ICEPHILOWERINGIMPL_H | 
|  | #define SUBZERO_SRC_ICEPHILOWERINGIMPL_H | 
|  |  | 
|  | #include "IceCfg.h" | 
|  | #include "IceCfgNode.h" | 
|  | #include "IceDefs.h" | 
|  | #include "IceInst.h" | 
|  | #include "IceOperand.h" | 
|  |  | 
|  | namespace Ice { | 
|  | namespace PhiLowering { | 
|  |  | 
|  | /// Turn an i64 Phi instruction into a pair of i32 Phi instructions, to preserve | 
|  | /// integrity of liveness analysis. This is needed for 32-bit targets. This | 
|  | /// assumes the 32-bit target has loOperand, hiOperand, and legalizeUndef | 
|  | /// methods. Undef values are also legalized, since loOperand() and hiOperand() | 
|  | /// don't expect Undef input. | 
|  | template <class TargetT> | 
|  | void prelowerPhis32Bit(TargetT *Target, CfgNode *Node, Cfg *Func) { | 
|  | for (Inst &I : Node->getPhis()) { | 
|  | auto *Phi = llvm::dyn_cast<InstPhi>(&I); | 
|  | if (Phi->isDeleted()) | 
|  | continue; | 
|  | Variable *Dest = Phi->getDest(); | 
|  | Type DestTy = Dest->getType(); | 
|  | if (DestTy == IceType_i64) { | 
|  | auto *DestLo = llvm::cast<Variable>(Target->loOperand(Dest)); | 
|  | auto *DestHi = llvm::cast<Variable>(Target->hiOperand(Dest)); | 
|  | auto *PhiLo = InstPhi::create(Func, Phi->getSrcSize(), DestLo); | 
|  | auto *PhiHi = InstPhi::create(Func, Phi->getSrcSize(), DestHi); | 
|  | for (SizeT I = 0; I < Phi->getSrcSize(); ++I) { | 
|  | Operand *Src = Phi->getSrc(I); | 
|  | CfgNode *Label = Phi->getLabel(I); | 
|  | Src = Target->legalizeUndef(Src); | 
|  | PhiLo->addArgument(Target->loOperand(Src), Label); | 
|  | PhiHi->addArgument(Target->hiOperand(Src), Label); | 
|  | } | 
|  | Node->getPhis().push_back(PhiLo); | 
|  | Node->getPhis().push_back(PhiHi); | 
|  | Phi->setDeleted(); | 
|  | } else if (isVectorType(DestTy) && | 
|  | Target->shouldSplitToVariableVecOn32(DestTy)) { | 
|  | auto *DstVec = llvm::cast<VariableVecOn32>(Dest); | 
|  | SizeT Idx = 0; | 
|  | for (Variable *DestElem : DstVec->getContainers()) { | 
|  | auto *PhiElem = InstPhi::create(Func, Phi->getSrcSize(), DestElem); | 
|  | for (SizeT I = 0; I < Phi->getSrcSize(); ++I) { | 
|  | Operand *Src = Phi->getSrc(I); | 
|  | CfgNode *Label = Phi->getLabel(I); | 
|  | Src = Target->legalizeUndef(Src); | 
|  | auto *SrcVec = llvm::cast<VariableVecOn32>(Src); | 
|  | PhiElem->addArgument(SrcVec->getContainers()[Idx], Label); | 
|  | } | 
|  | ++Idx; | 
|  | Node->getPhis().push_back(PhiElem); | 
|  | } | 
|  | Phi->setDeleted(); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | } // end of namespace PhiLowering | 
|  | } // end of namespace Ice | 
|  |  | 
|  | #endif // SUBZERO_SRC_ICEPHILOWERINGIMPL_H |