blob: 72a3e8ce3dfe7051e0e1641ee86e6c351ec03178 [file] [log] [blame]
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001//===- subzero/src/IceTargetLowering.cpp - Basic lowering implementation --===//
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// This file implements the skeleton of the TargetLowering class,
11// specifically invoking the appropriate lowering method for a given
12// instruction kind and driving global register allocation. It also
13// implements the non-deleted instruction iteration in
14// LoweringContext.
15//
16//===----------------------------------------------------------------------===//
17
18#include "IceCfg.h" // setError()
19#include "IceCfgNode.h"
20#include "IceOperand.h"
Jim Stichnothd97c7df2014-06-04 11:57:08 -070021#include "IceRegAlloc.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070022#include "IceTargetLowering.h"
23#include "IceTargetLoweringX8632.h"
24
25namespace Ice {
26
27void LoweringContext::init(CfgNode *N) {
28 Node = N;
29 Cur = getNode()->getInsts().begin();
30 End = getNode()->getInsts().end();
31 skipDeleted(Cur);
32 Next = Cur;
33 advance(Next);
34}
35
36void LoweringContext::insert(Inst *Inst) {
37 getNode()->getInsts().insert(Next, Inst);
38 Inst->updateVars(getNode());
39}
40
41void LoweringContext::skipDeleted(InstList::iterator &I) {
42 while (I != End && (*I)->isDeleted())
43 ++I;
44}
45
46void LoweringContext::advance(InstList::iterator &I) {
47 if (I != End) {
48 ++I;
49 skipDeleted(I);
50 }
51}
52
53TargetLowering *TargetLowering::createLowering(TargetArch Target, Cfg *Func) {
54 // These statements can be #ifdef'd to specialize the code generator
55 // to a subset of the available targets. TODO: use CRTP.
56 if (Target == Target_X8632)
57 return TargetX8632::create(Func);
58#if 0
59 if (Target == Target_X8664)
60 return IceTargetX8664::create(Func);
61 if (Target == Target_ARM32)
62 return IceTargetARM32::create(Func);
63 if (Target == Target_ARM64)
64 return IceTargetARM64::create(Func);
65#endif
66 Func->setError("Unsupported target");
67 return NULL;
68}
69
Jim Stichnothd97c7df2014-06-04 11:57:08 -070070void TargetLowering::doAddressOpt() {
71 if (llvm::isa<InstLoad>(*Context.getCur()))
72 doAddressOptLoad();
73 else if (llvm::isa<InstStore>(*Context.getCur()))
74 doAddressOptStore();
75 Context.advanceCur();
76 Context.advanceNext();
77}
78
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070079// Lowers a single instruction according to the information in
80// Context, by checking the Context.Cur instruction kind and calling
81// the appropriate lowering method. The lowering method should insert
82// target instructions at the Cur.Next insertion point, and should not
83// delete the Context.Cur instruction or advance Context.Cur.
84//
85// The lowering method may look ahead in the instruction stream as
86// desired, and lower additional instructions in conjunction with the
87// current one, for example fusing a compare and branch. If it does,
88// it should advance Context.Cur to point to the next non-deleted
89// instruction to process, and it should delete any additional
90// instructions it consumes.
91void TargetLowering::lower() {
92 assert(!Context.atEnd());
93 Inst *Inst = *Context.getCur();
94 switch (Inst->getKind()) {
95 case Inst::Alloca:
96 lowerAlloca(llvm::dyn_cast<InstAlloca>(Inst));
97 break;
98 case Inst::Arithmetic:
99 lowerArithmetic(llvm::dyn_cast<InstArithmetic>(Inst));
100 break;
101 case Inst::Assign:
102 lowerAssign(llvm::dyn_cast<InstAssign>(Inst));
103 break;
104 case Inst::Br:
105 lowerBr(llvm::dyn_cast<InstBr>(Inst));
106 break;
107 case Inst::Call:
108 lowerCall(llvm::dyn_cast<InstCall>(Inst));
109 break;
110 case Inst::Cast:
111 lowerCast(llvm::dyn_cast<InstCast>(Inst));
112 break;
113 case Inst::Fcmp:
114 lowerFcmp(llvm::dyn_cast<InstFcmp>(Inst));
115 break;
116 case Inst::Icmp:
117 lowerIcmp(llvm::dyn_cast<InstIcmp>(Inst));
118 break;
119 case Inst::Load:
120 lowerLoad(llvm::dyn_cast<InstLoad>(Inst));
121 break;
122 case Inst::Phi:
123 lowerPhi(llvm::dyn_cast<InstPhi>(Inst));
124 break;
125 case Inst::Ret:
126 lowerRet(llvm::dyn_cast<InstRet>(Inst));
127 break;
128 case Inst::Select:
129 lowerSelect(llvm::dyn_cast<InstSelect>(Inst));
130 break;
131 case Inst::Store:
132 lowerStore(llvm::dyn_cast<InstStore>(Inst));
133 break;
134 case Inst::Switch:
135 lowerSwitch(llvm::dyn_cast<InstSwitch>(Inst));
136 break;
137 case Inst::Unreachable:
138 lowerUnreachable(llvm::dyn_cast<InstUnreachable>(Inst));
139 break;
140 case Inst::FakeDef:
141 case Inst::FakeUse:
142 case Inst::FakeKill:
143 case Inst::Target:
144 // These are all Target instruction types and shouldn't be
145 // encountered at this stage.
146 Func->setError("Can't lower unsupported instruction type");
147 break;
148 }
149 Inst->setDeleted();
150
151 postLower();
152
153 Context.advanceCur();
154 Context.advanceNext();
155}
156
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700157// Drives register allocation, allowing all physical registers (except
158// perhaps for the frame pointer) to be allocated. This set of
159// registers could potentially be parameterized if we want to restrict
160// registers e.g. for performance testing.
161void TargetLowering::regAlloc() {
162 LinearScan LinearScan(Func);
163 RegSetMask RegInclude = RegSet_None;
164 RegSetMask RegExclude = RegSet_None;
165 RegInclude |= RegSet_CallerSave;
166 RegInclude |= RegSet_CalleeSave;
167 RegExclude |= RegSet_StackPointer;
168 if (hasFramePointer())
169 RegExclude |= RegSet_FramePointer;
170 llvm::SmallBitVector RegMask = getRegisterSet(RegInclude, RegExclude);
171 LinearScan.scan(RegMask);
172}
173
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700174} // end of namespace Ice