Home | History | Annotate | Download | only in src
      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