blob: a5dd39aa30dcf53061ce3fe339c321c14baa0c6c [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;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700119 case Inst::IntrinsicCall:
120 lowerIntrinsicCall(llvm::dyn_cast<InstIntrinsicCall>(Inst));
121 break;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700122 case Inst::Load:
123 lowerLoad(llvm::dyn_cast<InstLoad>(Inst));
124 break;
125 case Inst::Phi:
126 lowerPhi(llvm::dyn_cast<InstPhi>(Inst));
127 break;
128 case Inst::Ret:
129 lowerRet(llvm::dyn_cast<InstRet>(Inst));
130 break;
131 case Inst::Select:
132 lowerSelect(llvm::dyn_cast<InstSelect>(Inst));
133 break;
134 case Inst::Store:
135 lowerStore(llvm::dyn_cast<InstStore>(Inst));
136 break;
137 case Inst::Switch:
138 lowerSwitch(llvm::dyn_cast<InstSwitch>(Inst));
139 break;
140 case Inst::Unreachable:
141 lowerUnreachable(llvm::dyn_cast<InstUnreachable>(Inst));
142 break;
143 case Inst::FakeDef:
144 case Inst::FakeUse:
145 case Inst::FakeKill:
146 case Inst::Target:
147 // These are all Target instruction types and shouldn't be
148 // encountered at this stage.
149 Func->setError("Can't lower unsupported instruction type");
150 break;
151 }
152 Inst->setDeleted();
153
154 postLower();
155
156 Context.advanceCur();
157 Context.advanceNext();
158}
159
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700160// Drives register allocation, allowing all physical registers (except
161// perhaps for the frame pointer) to be allocated. This set of
162// registers could potentially be parameterized if we want to restrict
163// registers e.g. for performance testing.
164void TargetLowering::regAlloc() {
165 LinearScan LinearScan(Func);
166 RegSetMask RegInclude = RegSet_None;
167 RegSetMask RegExclude = RegSet_None;
168 RegInclude |= RegSet_CallerSave;
169 RegInclude |= RegSet_CalleeSave;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700170 if (hasFramePointer())
171 RegExclude |= RegSet_FramePointer;
172 llvm::SmallBitVector RegMask = getRegisterSet(RegInclude, RegExclude);
173 LinearScan.scan(RegMask);
174}
175
Jim Stichnothde4ca712014-06-29 08:13:48 -0700176TargetGlobalInitLowering *
177TargetGlobalInitLowering::createLowering(TargetArch Target,
178 GlobalContext *Ctx) {
179 // These statements can be #ifdef'd to specialize the code generator
180 // to a subset of the available targets. TODO: use CRTP.
181 if (Target == Target_X8632)
182 return TargetGlobalInitX8632::create(Ctx);
183#if 0
184 if (Target == Target_X8664)
185 return IceTargetGlobalInitX8664::create(Ctx);
186 if (Target == Target_ARM32)
187 return IceTargetGlobalInitARM32::create(Ctx);
188 if (Target == Target_ARM64)
189 return IceTargetGlobalInitARM64::create(Ctx);
190#endif
191 llvm_unreachable("Unsupported target");
192 return NULL;
193}
194
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700195} // end of namespace Ice