blob: b602e8152f99ad206f4305c39a6132a2df61aca8 [file] [log] [blame]
Jan Voung53483692015-07-16 10:47:46 -07001//===------ 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
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Utilities for targets to lower Phis.
Jan Voung53483692015-07-16 10:47:46 -070012///
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
24namespace Ice {
25namespace PhiLowering {
26
Andrew Scull57e12682015-09-16 11:30:19 -070027/// 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.
Jan Voung53483692015-07-16 10:47:46 -070032template <class TargetT>
33void prelowerPhis32Bit(TargetT *Target, CfgNode *Node, Cfg *Func) {
34 for (Inst &I : Node->getPhis()) {
Jim Stichnoth5bff61c2015-10-28 09:26:00 -070035 auto *Phi = llvm::dyn_cast<InstPhi>(&I);
Jan Voung53483692015-07-16 10:47:46 -070036 if (Phi->isDeleted())
37 continue;
38 Variable *Dest = Phi->getDest();
Jaydeep Patil2bbda7f2017-01-10 21:48:58 -080039 Type DestTy = Dest->getType();
40 if (DestTy == IceType_i64) {
Jim Stichnoth54f3d512015-12-11 09:53:00 -080041 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);
Jan Voung53483692015-07-16 10:47:46 -070045 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();
Jaydeep Patil2bbda7f2017-01-10 21:48:58 -080055 } 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();
Jan Voung53483692015-07-16 10:47:46 -070072 }
73 }
74}
75
76} // end of namespace PhiLowering
77} // end of namespace Ice
78
79#endif // SUBZERO_SRC_ICEPHILOWERINGIMPL_H