//===------ 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