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>
prelowerPhis32Bit(TargetT * Target,CfgNode * Node,Cfg * Func)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