blob: 5c50d2f53f6b5efe2b4a7b6fb2416c978cb60eb3 [file] [log] [blame]
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001//===- subzero/src/IceInst.h - High-level instructions ----------*- 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// This file declares the Inst class and its target-independent
11// subclasses, which represent the high-level Vanilla ICE instructions
12// and map roughly 1:1 to LLVM instructions.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef SUBZERO_SRC_ICEINST_H
17#define SUBZERO_SRC_ICEINST_H
18
19#include "IceDefs.h"
20#include "IceInst.def"
Jan Voung3bd9f1a2014-06-18 10:50:57 -070021#include "IceIntrinsics.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070022#include "IceTypes.h"
23
24// TODO: The Cfg structure, and instructions in particular, need to be
25// validated for things like valid operand types, valid branch
26// targets, proper ordering of Phi and non-Phi instructions, etc.
27// Most of the validity checking will be done in the bitcode reader.
28// We need a list of everything that should be validated, and tests
29// for each.
30
31namespace Ice {
32
Jim Stichnothb56c8f42014-09-26 09:28:46 -070033// Base instruction class for ICE. Inst has two subclasses:
34// InstHighLevel and InstTarget. High-level ICE instructions inherit
35// from InstHighLevel, and low-level (target-specific) ICE
36// instructions inherit from InstTarget.
Jim Stichnothf7c9a142014-04-29 10:52:43 -070037class Inst {
38public:
39 enum InstKind {
40 // Arbitrary (alphabetical) order, except put Unreachable first.
41 Unreachable,
42 Alloca,
43 Arithmetic,
44 Assign, // not part of LLVM/PNaCl bitcode
45 Br,
46 Call,
47 Cast,
Matt Wala49889232014-07-18 12:45:09 -070048 ExtractElement,
Jim Stichnothf7c9a142014-04-29 10:52:43 -070049 Fcmp,
50 Icmp,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070051 IntrinsicCall,
Matt Wala49889232014-07-18 12:45:09 -070052 InsertElement,
Jim Stichnothf7c9a142014-04-29 10:52:43 -070053 Load,
54 Phi,
55 Ret,
56 Select,
57 Store,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070058 Switch,
59 FakeDef, // not part of LLVM/PNaCl bitcode
60 FakeUse, // not part of LLVM/PNaCl bitcode
61 FakeKill, // not part of LLVM/PNaCl bitcode
62 Target // target-specific low-level ICE
63 // Anything >= Target is an InstTarget subclass.
Jim Stichnothf7c9a142014-04-29 10:52:43 -070064 };
65 InstKind getKind() const { return Kind; }
66
Jim Stichnothd97c7df2014-06-04 11:57:08 -070067 InstNumberT getNumber() const { return Number; }
68 void renumber(Cfg *Func);
69 static const InstNumberT NumberDeleted = -1;
70 static const InstNumberT NumberSentinel = 0;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070071
72 bool isDeleted() const { return Deleted; }
73 void setDeleted() { Deleted = true; }
Jim Stichnothd97c7df2014-06-04 11:57:08 -070074 void deleteIfDead();
Jim Stichnothf7c9a142014-04-29 10:52:43 -070075
76 bool hasSideEffects() const { return HasSideEffects; }
77
78 Variable *getDest() const { return Dest; }
79
80 SizeT getSrcSize() const { return NumSrcs; }
81 Operand *getSrc(SizeT I) const {
82 assert(I < getSrcSize());
83 return Srcs[I];
84 }
85
Jim Stichnothd97c7df2014-06-04 11:57:08 -070086 bool isLastUse(const Operand *Src) const;
87
Jim Stichnothf7c9a142014-04-29 10:52:43 -070088 // Returns a list of out-edges corresponding to a terminator
89 // instruction, which is the last instruction of the block.
90 virtual NodeList getTerminatorEdges() const {
91 // All valid terminator instructions override this method. For
92 // the default implementation, we assert in case some CfgNode
93 // is constructed without a terminator instruction at the end.
94 llvm_unreachable(
95 "getTerminatorEdges() called on a non-terminator instruction");
96 return NodeList();
97 }
98
Jim Stichnothad403532014-09-25 12:44:17 -070099 virtual bool isSimpleAssign() const { return false; }
100
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700101 void livenessLightweight(Cfg *Func, llvm::BitVector &Live);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700102 void liveness(InstNumberT InstNumber, llvm::BitVector &Live,
103 Liveness *Liveness, const CfgNode *Node);
Jim Stichnoth18735602014-09-16 19:59:35 -0700104
105 // Get the number of native instructions that this instruction
106 // ultimately emits. By default, high-level instructions don't
107 // result in any native instructions, and a target-specific
108 // instruction results in a single native instruction.
109 virtual uint32_t getEmitInstCount() const { return 0; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700110 virtual void emit(const Cfg *Func) const = 0;
111 virtual void emitIAS(const Cfg *Func) const = 0;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700112 virtual void dump(const Cfg *Func) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700113 virtual void dumpExtras(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700114 void dumpDecorated(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700115 void emitSources(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700116 void dumpSources(const Cfg *Func) const;
117 void dumpDest(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700118 virtual bool isRedundantAssign() const { return false; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700119
120 virtual ~Inst() {}
121
122protected:
123 Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest);
124 void addSource(Operand *Src) {
125 assert(Src);
126 assert(NumSrcs < MaxSrcs);
127 Srcs[NumSrcs++] = Src;
128 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700129 void setLastUse(SizeT VarIndex) {
130 if (VarIndex < CHAR_BIT * sizeof(LiveRangesEnded))
131 LiveRangesEnded |= (((LREndedBits)1u) << VarIndex);
132 }
133 void resetLastUses() { LiveRangesEnded = 0; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700134 // The destroy() method lets the instruction cleanly release any
135 // memory that was allocated via the Cfg's allocator.
136 virtual void destroy(Cfg *Func) { Func->deallocateArrayOf<Operand *>(Srcs); }
137
138 const InstKind Kind;
139 // Number is the instruction number for describing live ranges.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700140 InstNumberT Number;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700141 // Deleted means irrevocably deleted.
142 bool Deleted;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700143 // Dead means pending deletion after liveness analysis converges.
144 bool Dead;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700145 // HasSideEffects means the instruction is something like a function
146 // call or a volatile load that can't be removed even if its Dest
147 // variable is not live.
148 bool HasSideEffects;
149
150 Variable *Dest;
151 const SizeT MaxSrcs; // only used for assert
152 SizeT NumSrcs;
153 Operand **Srcs;
154
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700155 // LiveRangesEnded marks which Variables' live ranges end in this
156 // instruction. An instruction can have an arbitrary number of
157 // source operands (e.g. a call instruction), and each source
158 // operand can contain 0 or 1 Variable (and target-specific operands
159 // could contain more than 1 Variable). All the variables in an
160 // instruction are conceptually flattened and each variable is
161 // mapped to one bit position of the LiveRangesEnded bit vector.
162 // Only the first CHAR_BIT * sizeof(LREndedBits) variables are
163 // tracked this way.
164 typedef uint32_t LREndedBits; // only first 32 src operands tracked, sorry
165 LREndedBits LiveRangesEnded;
166
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700167private:
168 Inst(const Inst &) LLVM_DELETED_FUNCTION;
169 Inst &operator=(const Inst &) LLVM_DELETED_FUNCTION;
170};
171
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700172class InstHighLevel : public Inst {
173 InstHighLevel(const InstHighLevel &) LLVM_DELETED_FUNCTION;
174 InstHighLevel &operator=(const InstHighLevel &) LLVM_DELETED_FUNCTION;
175
176protected:
177 InstHighLevel(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
178 : Inst(Func, Kind, MaxSrcs, Dest) {}
179 void emit(const Cfg * /*Func*/) const override {
180 llvm_unreachable("emit() called on a non-lowered instruction");
181 }
182 void emitIAS(const Cfg * /*Func*/) const override {
183 llvm_unreachable("emitIAS() called on a non-lowered instruction");
184 }
185 ~InstHighLevel() override {}
186};
187
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700188// Alloca instruction. This captures the size in bytes as getSrc(0),
189// and the required alignment in bytes. The alignment must be either
190// 0 (no alignment required) or a power of 2.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700191class InstAlloca : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700192public:
193 static InstAlloca *create(Cfg *Func, Operand *ByteCount,
194 uint32_t AlignInBytes, Variable *Dest) {
195 return new (Func->allocateInst<InstAlloca>())
196 InstAlloca(Func, ByteCount, AlignInBytes, Dest);
197 }
198 uint32_t getAlignInBytes() const { return AlignInBytes; }
199 Operand *getSizeInBytes() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700200 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700201 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; }
202
203private:
204 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes,
205 Variable *Dest);
206 InstAlloca(const InstAlloca &) LLVM_DELETED_FUNCTION;
207 InstAlloca &operator=(const InstAlloca &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700208 ~InstAlloca() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700209 const uint32_t AlignInBytes;
210};
211
212// Binary arithmetic instruction. The source operands are captured in
213// getSrc(0) and getSrc(1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700214class InstArithmetic : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700215public:
216 enum OpKind {
217#define X(tag, str, commutative) tag,
218 ICEINSTARITHMETIC_TABLE
219#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700220 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700221 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700222
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700223 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest,
224 Operand *Source1, Operand *Source2) {
225 return new (Func->allocateInst<InstArithmetic>())
226 InstArithmetic(Func, Op, Dest, Source1, Source2);
227 }
228 OpKind getOp() const { return Op; }
Karl Schimpfd6064a12014-08-27 15:34:58 -0700229 static const char *getOpName(OpKind Op);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700230 bool isCommutative() const;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700231 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700232 static bool classof(const Inst *Inst) {
233 return Inst->getKind() == Arithmetic;
234 }
235
236private:
237 InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1,
238 Operand *Source2);
239 InstArithmetic(const InstArithmetic &) LLVM_DELETED_FUNCTION;
240 InstArithmetic &operator=(const InstArithmetic &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700241 ~InstArithmetic() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700242
243 const OpKind Op;
244};
245
246// Assignment instruction. The source operand is captured in
247// getSrc(0). This is not part of the LLVM bitcode, but is a useful
248// abstraction for some of the lowering. E.g., if Phi instruction
249// lowering happens before target lowering, or for representing an
250// Inttoptr instruction, or as an intermediate step for lowering a
251// Load instruction.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700252class InstAssign : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700253public:
254 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) {
255 return new (Func->allocateInst<InstAssign>())
256 InstAssign(Func, Dest, Source);
257 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700258 bool isSimpleAssign() const override { return true; }
259 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700260 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; }
261
262private:
263 InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
264 InstAssign(const InstAssign &) LLVM_DELETED_FUNCTION;
265 InstAssign &operator=(const InstAssign &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700266 ~InstAssign() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700267};
268
269// Branch instruction. This represents both conditional and
270// unconditional branches.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700271class InstBr : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700272public:
273 // Create a conditional branch. If TargetTrue==TargetFalse, it is
274 // optimized to an unconditional branch.
275 static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue,
276 CfgNode *TargetFalse) {
277 return new (Func->allocateInst<InstBr>())
278 InstBr(Func, Source, TargetTrue, TargetFalse);
279 }
280 // Create an unconditional branch.
281 static InstBr *create(Cfg *Func, CfgNode *Target) {
282 return new (Func->allocateInst<InstBr>()) InstBr(Func, Target);
283 }
284 bool isUnconditional() const { return getTargetTrue() == NULL; }
285 Operand *getCondition() const {
286 assert(!isUnconditional());
287 return getSrc(0);
288 }
289 CfgNode *getTargetTrue() const { return TargetTrue; }
290 CfgNode *getTargetFalse() const { return TargetFalse; }
291 CfgNode *getTargetUnconditional() const {
292 assert(isUnconditional());
293 return getTargetFalse();
294 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700295 NodeList getTerminatorEdges() const override;
296 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700297 static bool classof(const Inst *Inst) { return Inst->getKind() == Br; }
298
299private:
300 // Conditional branch
301 InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse);
302 // Unconditional branch
303 InstBr(Cfg *Func, CfgNode *Target);
304 InstBr(const InstBr &) LLVM_DELETED_FUNCTION;
305 InstBr &operator=(const InstBr &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700306 ~InstBr() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700307
308 CfgNode *const TargetFalse; // Doubles as unconditional branch target
309 CfgNode *const TargetTrue; // NULL if unconditional branch
310};
311
312// Call instruction. The call target is captured as getSrc(0), and
313// arg I is captured as getSrc(I+1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700314class InstCall : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700315public:
316 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
Karl Schimpf8df26f32014-09-19 09:33:26 -0700317 Operand *CallTarget, bool HasTailCall) {
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700318 // Set HasSideEffects to true so that the call instruction can't be
319 // dead-code eliminated. IntrinsicCalls can override this if the
320 // particular intrinsic is deletable and has no side-effects.
321 const bool HasSideEffects = true;
322 const InstKind Kind = Inst::Call;
Karl Schimpf8df26f32014-09-19 09:33:26 -0700323 return new (Func->allocateInst<InstCall>()) InstCall(
324 Func, NumArgs, Dest, CallTarget, HasTailCall, HasSideEffects, Kind);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700325 }
326 void addArg(Operand *Arg) { addSource(Arg); }
327 Operand *getCallTarget() const { return getSrc(0); }
328 Operand *getArg(SizeT I) const { return getSrc(I + 1); }
329 SizeT getNumArgs() const { return getSrcSize() - 1; }
Karl Schimpf8df26f32014-09-19 09:33:26 -0700330 bool isTailcall() const { return HasTailCall; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700331 void dump(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700332 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; }
Karl Schimpf8df26f32014-09-19 09:33:26 -0700333 Type getReturnType() const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700334
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700335protected:
336 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget,
Karl Schimpf8df26f32014-09-19 09:33:26 -0700337 bool HasTailCall, bool HasSideEff, InstKind Kind)
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700338 : InstHighLevel(Func, Kind, NumArgs + 1, Dest), HasTailCall(HasTailCall) {
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700339 HasSideEffects = HasSideEff;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700340 addSource(CallTarget);
341 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700342 ~InstCall() override {}
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700343
344private:
Karl Schimpf8df26f32014-09-19 09:33:26 -0700345 bool HasTailCall;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700346 InstCall(const InstCall &) LLVM_DELETED_FUNCTION;
347 InstCall &operator=(const InstCall &) LLVM_DELETED_FUNCTION;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700348};
349
350// Cast instruction (a.k.a. conversion operation).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700351class InstCast : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700352public:
353 enum OpKind {
354#define X(tag, str) tag,
355 ICEINSTCAST_TABLE
356#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700357 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700358 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700359
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700360 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
361 Operand *Source) {
362 return new (Func->allocateInst<InstCast>())
363 InstCast(Func, CastKind, Dest, Source);
364 }
365 OpKind getCastKind() const { return CastKind; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700366 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700367 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
368
369private:
370 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
371 InstCast(const InstCast &) LLVM_DELETED_FUNCTION;
372 InstCast &operator=(const InstCast &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700373 ~InstCast() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700374 const OpKind CastKind;
375};
376
Matt Wala49889232014-07-18 12:45:09 -0700377// ExtractElement instruction.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700378class InstExtractElement : public InstHighLevel {
Matt Wala49889232014-07-18 12:45:09 -0700379public:
380 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
381 Operand *Source2) {
382 return new (Func->allocateInst<InstExtractElement>())
383 InstExtractElement(Func, Dest, Source1, Source2);
384 }
385
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700386 void dump(const Cfg *Func) const override;
Matt Wala49889232014-07-18 12:45:09 -0700387 static bool classof(const Inst *Inst) {
388 return Inst->getKind() == ExtractElement;
389 }
390
391private:
392 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
393 Operand *Source2);
394 InstExtractElement(const InstExtractElement &) LLVM_DELETED_FUNCTION;
395 InstExtractElement &
396 operator=(const InstExtractElement &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700397 ~InstExtractElement() override {}
Matt Wala49889232014-07-18 12:45:09 -0700398};
399
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700400// Floating-point comparison instruction. The source operands are
401// captured in getSrc(0) and getSrc(1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700402class InstFcmp : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700403public:
404 enum FCond {
405#define X(tag, str) tag,
406 ICEINSTFCMP_TABLE
407#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700408 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700409 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700410
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700411 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
412 Operand *Source1, Operand *Source2) {
413 return new (Func->allocateInst<InstFcmp>())
414 InstFcmp(Func, Condition, Dest, Source1, Source2);
415 }
416 FCond getCondition() const { return Condition; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700417 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700418 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
419
420private:
421 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
422 Operand *Source2);
423 InstFcmp(const InstFcmp &) LLVM_DELETED_FUNCTION;
424 InstFcmp &operator=(const InstFcmp &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700425 ~InstFcmp() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700426 const FCond Condition;
427};
428
429// Integer comparison instruction. The source operands are captured
430// in getSrc(0) and getSrc(1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700431class InstIcmp : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700432public:
433 enum ICond {
434#define X(tag, str) tag,
435 ICEINSTICMP_TABLE
436#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700437 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700438 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700439
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700440 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
441 Operand *Source1, Operand *Source2) {
442 return new (Func->allocateInst<InstIcmp>())
443 InstIcmp(Func, Condition, Dest, Source1, Source2);
444 }
445 ICond getCondition() const { return Condition; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700446 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700447 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
448
449private:
450 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
451 Operand *Source2);
452 InstIcmp(const InstIcmp &) LLVM_DELETED_FUNCTION;
453 InstIcmp &operator=(const InstIcmp &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700454 ~InstIcmp() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700455 const ICond Condition;
456};
457
Matt Wala49889232014-07-18 12:45:09 -0700458// InsertElement instruction.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700459class InstInsertElement : public InstHighLevel {
Matt Wala49889232014-07-18 12:45:09 -0700460public:
461 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
462 Operand *Source2, Operand *Source3) {
463 return new (Func->allocateInst<InstInsertElement>())
464 InstInsertElement(Func, Dest, Source1, Source2, Source3);
465 }
466
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700467 void dump(const Cfg *Func) const override;
Matt Wala49889232014-07-18 12:45:09 -0700468 static bool classof(const Inst *Inst) {
469 return Inst->getKind() == InsertElement;
470 }
471
472private:
473 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
474 Operand *Source2, Operand *Source3);
475 InstInsertElement(const InstInsertElement &) LLVM_DELETED_FUNCTION;
476 InstInsertElement &operator=(const InstInsertElement &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700477 ~InstInsertElement() override {}
Matt Wala49889232014-07-18 12:45:09 -0700478};
479
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700480// Call to an intrinsic function. The call target is captured as getSrc(0),
481// and arg I is captured as getSrc(I+1).
482class InstIntrinsicCall : public InstCall {
483public:
484 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
485 Operand *CallTarget,
486 const Intrinsics::IntrinsicInfo &Info) {
487 return new (Func->allocateInst<InstIntrinsicCall>())
488 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
489 }
490 static bool classof(const Inst *Inst) {
491 return Inst->getKind() == IntrinsicCall;
492 }
493
494 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; }
495
496private:
497 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest,
498 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info)
Karl Schimpf8df26f32014-09-19 09:33:26 -0700499 : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects,
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700500 Inst::IntrinsicCall),
501 Info(Info) {}
502 InstIntrinsicCall(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION;
503 InstIntrinsicCall &operator=(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700504 ~InstIntrinsicCall() override {}
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700505 const Intrinsics::IntrinsicInfo Info;
506};
507
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700508// Load instruction. The source address is captured in getSrc(0).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700509class InstLoad : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700510public:
Karl Schimpf41689df2014-09-10 14:36:07 -0700511 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr,
512 uint32_t align = 1) {
513 // TODO(kschimpf) Stop ignoring alignment specification.
514 (void)align;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700515 return new (Func->allocateInst<InstLoad>())
516 InstLoad(Func, Dest, SourceAddr);
517 }
518 Operand *getSourceAddress() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700519 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700520 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; }
521
522private:
523 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
524 InstLoad(const InstLoad &) LLVM_DELETED_FUNCTION;
525 InstLoad &operator=(const InstLoad &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700526 ~InstLoad() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700527};
528
529// Phi instruction. For incoming edge I, the node is Labels[I] and
530// the Phi source operand is getSrc(I).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700531class InstPhi : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700532public:
533 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
534 return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
535 }
536 void addArgument(Operand *Source, CfgNode *Label);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700537 Operand *getOperandForTarget(CfgNode *Target) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700538 void livenessPhiOperand(llvm::BitVector &Live, CfgNode *Target,
539 Liveness *Liveness);
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700540 Inst *lower(Cfg *Func);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700541 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700542 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
543
544private:
545 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest);
546 InstPhi(const InstPhi &) LLVM_DELETED_FUNCTION;
547 InstPhi &operator=(const InstPhi &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700548 void destroy(Cfg *Func) override {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700549 Func->deallocateArrayOf<CfgNode *>(Labels);
550 Inst::destroy(Func);
551 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700552 ~InstPhi() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700553
554 // Labels[] duplicates the InEdges[] information in the enclosing
555 // CfgNode, but the Phi instruction is created before InEdges[]
556 // is available, so it's more complicated to share the list.
557 CfgNode **Labels;
558};
559
560// Ret instruction. The return value is captured in getSrc(0), but if
561// there is no return value (void-type function), then
562// getSrcSize()==0 and hasRetValue()==false.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700563class InstRet : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700564public:
565 static InstRet *create(Cfg *Func, Operand *RetValue = NULL) {
566 return new (Func->allocateInst<InstRet>()) InstRet(Func, RetValue);
567 }
568 bool hasRetValue() const { return getSrcSize(); }
569 Operand *getRetValue() const {
570 assert(hasRetValue());
571 return getSrc(0);
572 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700573 NodeList getTerminatorEdges() const override { return NodeList(); }
574 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700575 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; }
576
577private:
578 InstRet(Cfg *Func, Operand *RetValue);
579 InstRet(const InstRet &) LLVM_DELETED_FUNCTION;
580 InstRet &operator=(const InstRet &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700581 ~InstRet() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700582};
583
584// Select instruction. The condition, true, and false operands are captured.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700585class InstSelect : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700586public:
587 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
588 Operand *SourceTrue, Operand *SourceFalse) {
589 return new (Func->allocateInst<InstSelect>())
590 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
591 }
592 Operand *getCondition() const { return getSrc(0); }
593 Operand *getTrueOperand() const { return getSrc(1); }
594 Operand *getFalseOperand() const { return getSrc(2); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700595 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700596 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; }
597
598private:
599 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
600 Operand *Source2);
601 InstSelect(const InstSelect &) LLVM_DELETED_FUNCTION;
602 InstSelect &operator=(const InstSelect &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700603 ~InstSelect() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700604};
605
606// Store instruction. The address operand is captured, along with the
607// data operand to be stored into the address.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700608class InstStore : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700609public:
Karl Schimpf41689df2014-09-10 14:36:07 -0700610 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr,
611 uint32_t align = 1) {
612 // TODO(kschimpf) Stop ignoring alignment specification.
613 (void)align;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700614 return new (Func->allocateInst<InstStore>()) InstStore(Func, Data, Addr);
615 }
616 Operand *getAddr() const { return getSrc(1); }
617 Operand *getData() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700618 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700619 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; }
620
621private:
622 InstStore(Cfg *Func, Operand *Data, Operand *Addr);
623 InstStore(const InstStore &) LLVM_DELETED_FUNCTION;
624 InstStore &operator=(const InstStore &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700625 ~InstStore() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700626};
627
628// Switch instruction. The single source operand is captured as
629// getSrc(0).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700630class InstSwitch : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700631public:
632 static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source,
633 CfgNode *LabelDefault) {
634 return new (Func->allocateInst<InstSwitch>())
635 InstSwitch(Func, NumCases, Source, LabelDefault);
636 }
637 Operand *getComparison() const { return getSrc(0); }
638 CfgNode *getLabelDefault() const { return LabelDefault; }
639 SizeT getNumCases() const { return NumCases; }
640 uint64_t getValue(SizeT I) const {
641 assert(I < NumCases);
642 return Values[I];
643 }
644 CfgNode *getLabel(SizeT I) const {
645 assert(I < NumCases);
646 return Labels[I];
647 }
648 void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700649 NodeList getTerminatorEdges() const override;
650 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700651 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; }
652
653private:
654 InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault);
655 InstSwitch(const InstSwitch &) LLVM_DELETED_FUNCTION;
656 InstSwitch &operator=(const InstSwitch &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700657 void destroy(Cfg *Func) override {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700658 Func->deallocateArrayOf<uint64_t>(Values);
659 Func->deallocateArrayOf<CfgNode *>(Labels);
660 Inst::destroy(Func);
661 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700662 ~InstSwitch() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700663
664 CfgNode *LabelDefault;
665 SizeT NumCases; // not including the default case
666 uint64_t *Values; // size is NumCases
667 CfgNode **Labels; // size is NumCases
668};
669
670// Unreachable instruction. This is a terminator instruction with no
671// operands.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700672class InstUnreachable : public InstHighLevel {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700673public:
674 static InstUnreachable *create(Cfg *Func) {
675 return new (Func->allocateInst<InstUnreachable>()) InstUnreachable(Func);
676 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700677 NodeList getTerminatorEdges() const override { return NodeList(); }
678 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700679 static bool classof(const Inst *Inst) {
680 return Inst->getKind() == Unreachable;
681 }
682
683private:
684 InstUnreachable(Cfg *Func);
685 InstUnreachable(const InstUnreachable &) LLVM_DELETED_FUNCTION;
686 InstUnreachable &operator=(const InstUnreachable &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700687 ~InstUnreachable() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700688};
689
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700690// FakeDef instruction. This creates a fake definition of a variable,
691// which is how we represent the case when an instruction produces
692// multiple results. This doesn't happen with high-level ICE
693// instructions, but might with lowered instructions. For example,
694// this would be a way to represent condition flags being modified by
695// an instruction.
696//
697// It's generally useful to set the optional source operand to be the
698// dest variable of the instruction that actually produces the FakeDef
699// dest. Otherwise, the original instruction could be dead-code
700// eliminated if its dest operand is unused, and therefore the FakeDef
701// dest wouldn't be properly initialized.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700702class InstFakeDef : public InstHighLevel {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700703public:
704 static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) {
705 return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
706 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700707 void emit(const Cfg *Func) const override;
708 void emitIAS(const Cfg *Func) const override { emit(Func); }
709 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700710 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; }
711
712private:
713 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
714 InstFakeDef(const InstFakeDef &) LLVM_DELETED_FUNCTION;
715 InstFakeDef &operator=(const InstFakeDef &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700716 ~InstFakeDef() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700717};
718
719// FakeUse instruction. This creates a fake use of a variable, to
720// keep the instruction that produces that variable from being
721// dead-code eliminated. This is useful in a variety of lowering
722// situations. The FakeUse instruction has no dest, so it can itself
723// never be dead-code eliminated.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700724class InstFakeUse : public InstHighLevel {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700725public:
726 static InstFakeUse *create(Cfg *Func, Variable *Src) {
727 return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src);
728 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700729 void emit(const Cfg *Func) const override;
730 void emitIAS(const Cfg *Func) const override { emit(Func); }
731 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700732 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; }
733
734private:
735 InstFakeUse(Cfg *Func, Variable *Src);
736 InstFakeUse(const InstFakeUse &) LLVM_DELETED_FUNCTION;
737 InstFakeUse &operator=(const InstFakeUse &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700738 ~InstFakeUse() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700739};
740
741// FakeKill instruction. This "kills" a set of variables by adding a
742// trivial live range at this instruction to each variable. The
743// primary use is to indicate that scratch registers are killed after
744// a call, so that the register allocator won't assign a scratch
745// register to a variable whose live range spans a call.
746//
747// The FakeKill instruction also holds a pointer to the instruction
748// that kills the set of variables, so that if that linked instruction
749// gets dead-code eliminated, the FakeKill instruction will as well.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700750class InstFakeKill : public InstHighLevel {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700751public:
752 static InstFakeKill *create(Cfg *Func, const VarList &KilledRegs,
753 const Inst *Linked) {
754 return new (Func->allocateInst<InstFakeKill>())
755 InstFakeKill(Func, KilledRegs, Linked);
756 }
757 const Inst *getLinked() const { return Linked; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700758 void emit(const Cfg *Func) const override;
759 void emitIAS(const Cfg *Func) const override { emit(Func); }
760 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700761 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
762
763private:
764 InstFakeKill(Cfg *Func, const VarList &KilledRegs, const Inst *Linked);
765 InstFakeKill(const InstFakeKill &) LLVM_DELETED_FUNCTION;
766 InstFakeKill &operator=(const InstFakeKill &) LLVM_DELETED_FUNCTION;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700767 ~InstFakeKill() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700768
769 // This instruction is ignored if Linked->isDeleted() is true.
770 const Inst *Linked;
771};
772
773// The Target instruction is the base class for all target-specific
774// instructions.
775class InstTarget : public Inst {
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700776 InstTarget(const InstTarget &) LLVM_DELETED_FUNCTION;
777 InstTarget &operator=(const InstTarget &) LLVM_DELETED_FUNCTION;
778
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700779public:
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700780 uint32_t getEmitInstCount() const override { return 1; }
781 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700782 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
783
784protected:
785 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
786 : Inst(Func, Kind, MaxSrcs, Dest) {
787 assert(Kind >= Target);
788 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700789 void emitIAS(const Cfg *Func) const override { emit(Func); }
790 ~InstTarget() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700791};
792
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700793} // end of namespace Ice
794
795#endif // SUBZERO_SRC_ICEINST_H