1 /**
2 Copyright: Copyright (c) 2017, Joakim Brännström. All rights reserved.
3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 */
6 module llvm_hiwrap.value.instruction;
7 
8 import llvm_hiwrap.types;
9 
10 import llvm_hiwrap.value.basic_block;
11 import llvm_hiwrap.value.value;
12 import llvm_hiwrap.value.user;
13 
14 /** Functions in this group relate to the inspection and manipulation of
15  * individual instructions.
16  *
17  * In the C++ API, an instruction is modeled by llvm::Instruction. This
18  * class has a large number of descendents. llvm::Instruction is a
19  * llvm::Value and in the C API, instructions are modeled by
20  * LLVMValueRef.
21  *
22  * This group also contains sub-groups which operate on specific
23  * llvm::Instruction types, e.g. llvm::CallInst.
24  */
25 struct InstructionValue {
26     import std.typecons : Nullable;
27     import llvm;
28     import llvm_hiwrap.value.metadata;
29 
30     LxInstructionValue value;
31     alias value this;
32 
33     auto asValue() {
34         return Value(value);
35     }
36 
37     UserValue asUser() {
38         return UserValue(value.LxUserValue);
39     }
40 
41     /// Determine whether an instruction has any metadata attached.
42     bool hasMetadata() {
43         return LLVMHasMetadata(this) != 0;
44     }
45 
46     /** Return metadata associated with an instruction value.
47      *
48      * TODO what is this KindID? very unsafe as is. Seems to be an attribute or
49      * it is what LLVMSetMetadata do?
50      * TODO what happens if KindID is "unknown"/out of range?
51      */
52     MetadataNodeValue metadata(uint kind) {
53         return LLVMGetMetadata(this, kind).LxValue.LxMetadataNodeValue.MetadataNodeValue;
54     }
55 
56     /** Set metadata associated with an instruction value.
57      */
58     void setMetadata(uint kind, Value v) {
59         LLVMSetMetadata(this, kind, v);
60     }
61 
62     /** Obtain the basic block to which an instruction belongs.
63      *
64      * @see llvm::Instruction::getParent()
65      */
66     BasicBlock parent() {
67         return LLVMGetInstructionParent(value).LxBasicBlock.BasicBlock;
68     }
69 
70     /** Obtain the instruction that occurs after the one specified.
71      *
72      * The next instruction will be from the same basic block.
73      *
74      * If this is the last instruction in a basic block, NULL will be
75      * returned.
76      */
77     Nullable!InstructionValue nextInstr() {
78         typeof(return) rval;
79         if (auto v = LLVMGetNextInstruction(value))
80             rval = v.LxValue.LxInstructionValue.InstructionValue;
81 
82         return rval;
83     }
84 
85     /** Obtain the instruction that occurred before this one.
86      *
87      * If the instruction is the first instruction in a basic block, NULL
88      * will be returned.
89      */
90     Nullable!InstructionValue prevInstr() {
91         typeof(return) rval;
92         if (auto v = LLVMGetPreviousInstruction(value))
93             rval = v.LxValue.LxInstructionValue.InstructionValue;
94 
95         return rval;
96     }
97 
98     /** Remove and delete an instruction.
99      *
100      * The instruction specified is removed from its containing building
101      * block but is kept alive.
102      *
103      * @see llvm::Instruction::removeFromParent()
104      */
105     void removeFromParent() {
106         LLVMInstructionRemoveFromParent(value);
107     }
108 
109     /** Remove and delete an instruction.
110      *
111      * The instruction specified is removed from its containing building
112      * block and then deleted.
113      *
114      * @see llvm::Instruction::eraseFromParent()
115      */
116     void eraseFromParent() {
117         LLVMInstructionEraseFromParent(value);
118     }
119 
120     /** Obtain the code opcode for an individual instruction.
121      *
122      * @see llvm::Instruction::getOpCode()
123      */
124     LxOpcode opcode() {
125         return cast(LxOpcode) LLVMGetInstructionOpcode(this);
126     }
127 
128     /** Obtain the predicate of an instruction.
129      *
130      * This is only valid for instructions that correspond to llvm::ICmpInst
131      * or llvm::ConstantExpr whose opcode is llvm::Instruction::ICmp.
132      *
133      * @see llvm::ICmpInst::getPredicate()
134      */
135     LxIntPredicate intPredicate() {
136         assert(opcode == LxOpcode.ICmp);
137         return cast(LxIntPredicate) LLVMGetICmpPredicate(this);
138     }
139 
140     /** Obtain the float predicate of an instruction.
141      *
142      * This is only valid for instructions that correspond to llvm::FCmpInst
143      * or llvm::ConstantExpr whose opcode is llvm::Instruction::FCmp.
144      *
145      * @see llvm::FCmpInst::getPredicate()
146      */
147     LxRealPredicate realPredicate() {
148         assert(opcode == LxOpcode.FCmp);
149         return cast(LxRealPredicate) LLVMGetFCmpPredicate(this);
150     }
151 
152     /** Create a copy of 'this' instruction that is identical in all ways
153      * except the following:
154      *   * The instruction has no parent
155      *   * The instruction has no name
156      *
157      * @see llvm::Instruction::clone()
158      */
159     InstructionValue clone() {
160         return LLVMInstructionClone(value).LxValue.LxInstructionValue.InstructionValue;
161     }
162 }
163 
164 /** Functions in this group apply to instructions that refer to call sites and
165  * invocations.
166  *
167  * These correspond to C++ types in the llvm::CallInst or InvokeInst class
168  * tree.
169  */
170 struct InstructionCallValue {
171     import llvm;
172     import llvm_hiwrap.value.function_;
173 
174     LxInstructionCallValue value;
175     alias value this;
176 
177     auto asValue() {
178         return Value(value);
179     }
180 
181     auto asInstr() {
182         return InstructionValue(value);
183     }
184 
185     /** Obtain the argument count for a call instruction.
186      *
187      * This expects an LLVMValueRef that corresponds to a llvm::CallInst or
188      * llvm::InvokeInst.
189      *
190      * @see llvm::CallInst::getNumArgOperands()
191      * @see llvm::InvokeInst::getNumArgOperands()
192      */
193     auto numArgOperands() {
194         return LLVMGetNumArgOperands(value);
195     }
196 
197     /**
198      * Set the calling convention for a call instruction.
199      *
200      * This expects an LLVMValueRef that corresponds to a llvm::CallInst or
201      * llvm::InvokeInst.
202      *
203      * @see llvm::CallInst::setCallingConv()
204      * @see llvm::InvokeInst::setCallingConv()
205      */
206     //void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC);
207 
208     /**
209      * Obtain the calling convention for a call instruction.
210      *
211      * This is the opposite of LLVMSetInstructionCallConv(). Reads its
212      * usage.
213      *
214      * @see LLVMSetInstructionCallConv()
215      */
216     //unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr);
217 
218     //void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,
219     //                                unsigned Align);
220     //
221     //void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
222     //                              LLVMAttributeRef A);
223     //unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C, LLVMAttributeIndex Idx);
224     //void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx,
225     //                               LLVMAttributeRef *Attrs);
226     //LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C,
227     //                                              LLVMAttributeIndex Idx,
228     //                                              unsigned KindID);
229     //LLVMAttributeRef LLVMGetCallSiteStringAttribute(LLVMValueRef C,
230     //                                                LLVMAttributeIndex Idx,
231     //                                                const char *K, unsigned KLen);
232     //void LLVMRemoveCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
233     //                                     unsigned KindID);
234     //void LLVMRemoveCallSiteStringAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
235     //                                       const char *K, unsigned KLen);
236 
237     /** Obtain the pointer to the function invoked by this instruction.
238      *
239      * This expects an LLVMValueRef that corresponds to a llvm::CallInst or
240      * llvm::InvokeInst.
241      *
242      * @see llvm::CallInst::getCalledValue()
243      * @see llvm::InvokeInst::getCalledValue()
244      *
245      * TODO maybe the return type should be a pointer instead?
246      */
247     FunctionValue calledValue() {
248         auto v = LLVMGetCalledValue(value);
249         return v.LxValue.LxUserValue.LxFunctionValue.FunctionValue;
250     }
251 
252     /** Obtain whether a call instruction is a tail call.
253      *
254      * This only works on llvm::CallInst instructions.
255      *
256      * @see llvm::CallInst::isTailCall()
257      */
258     bool isTailCall() {
259         return LLVMIsTailCall(value) != 0;
260     }
261 
262     /** Set whether a call instruction is a tail call.
263      *
264      * This only works on llvm::CallInst instructions.
265      *
266      * @see llvm::CallInst::setTailCall()
267      */
268     void setTailCall(bool onoff) {
269         LLVMSetTailCall(value, onoff ? 1 : 0);
270     }
271 
272     /** Return the normal destination basic block.
273      *
274      * This only works on llvm::InvokeInst instructions.
275      *
276      * @see llvm::InvokeInst::getNormalDest()
277      */
278     BasicBlock normalDest() {
279         return LLVMGetNormalDest(value).LxBasicBlock.BasicBlock;
280     }
281 
282     /** Return the unwind destination basic block.
283      *
284      * This only works on llvm::InvokeInst instructions.
285      *
286      * @see llvm::InvokeInst::getUnwindDest()
287      */
288     BasicBlock unwindDest() {
289         return LLVMGetUnwindDest(value).LxBasicBlock.BasicBlock;
290     }
291 
292     /** Set the normal destination basic block.
293      *
294      * This only works on llvm::InvokeInst instructions.
295      *
296      * @see llvm::InvokeInst::setNormalDest()
297      */
298     void setNormalDest(BasicBlock bb) {
299         LLVMSetNormalDest(value, bb);
300     }
301 
302     /** Set the unwind destination basic block.
303      *
304      * This only works on llvm::InvokeInst instructions.
305      *
306      * @see llvm::InvokeInst::setUnwindDest()
307      */
308     void setUnwindDest(BasicBlock bb) {
309         LLVMSetUnwindDest(value, bb);
310     }
311 }
312 
313 /** Functions in this group only apply to instructions that map to
314  * llvm::TerminatorInst instances.
315  */
316 struct InstructionTerminatorValue {
317     import llvm;
318 
319     LxInstructionTerminatorValue value;
320     alias value this;
321 
322     auto asValue() {
323         return Value(value);
324     }
325 
326     UserValue asUser() {
327         return UserValue(value.LxUserValue);
328     }
329 
330     auto asInstr() {
331         return InstructionValue(value);
332     }
333 
334     /// Returns: range over the successor blocks.
335     auto successors() {
336         return SuccessorsRange(this);
337     }
338 
339     /// Returns: the successor at the specified index
340     BasicBlock successor(size_t idx) {
341         assert(idx < LLVMGetNumSuccessors(value));
342         return LLVMGetSuccessor(value, cast(uint) idx).LxBasicBlock.BasicBlock;
343     }
344 
345     /** Update the specified successor to point at the provided block.
346      *
347      * @see llvm::TerminatorInst::setSuccessor
348      */
349     void setSuccessor(size_t idx, BasicBlock bb) {
350         LLVMSetSuccessor(value, cast(uint) idx, bb);
351     }
352 
353     /** Return if a branch is conditional.
354      *
355      * This only works on llvm::BranchInst instructions.
356      *
357      * @see llvm::BranchInst::isConditional
358      */
359     bool isConditional() {
360         return LLVMIsConditional(this) != 0;
361     }
362 
363     /** Return the condition of a branch instruction.
364      *
365      * This only works on llvm::BranchInst instructions.
366      *
367      * @see llvm::BranchInst::getCondition
368      */
369     Value condition() {
370         assert(isConditional);
371         return LLVMGetCondition(value).LxValue.Value;
372     }
373 
374     /**
375      * Set the condition of a branch instruction.
376      *
377      * This only works on llvm::BranchInst instructions.
378      *
379      * @see llvm::BranchInst::setCondition
380      */
381     //void LLVMSetCondition(LLVMValueRef Branch, LLVMValueRef Cond);
382 
383     /** Obtain the default destination basic block of a switch instruction.
384      *
385      * This only works on llvm::SwitchInst instructions.
386      *
387      * @see llvm::SwitchInst::getDefaultDest()
388      */
389     BasicBlock switchDefaultDest() {
390         assert(asInstr.opcode == LxOpcode.Switch);
391         return LLVMGetSwitchDefaultDest(value).LxBasicBlock.BasicBlock;
392     }
393 }
394 
395 /** Functions in this group only apply to instructions that map to
396  * llvm::AllocaInst instances.
397  */
398 struct InstructionAllocaValue {
399     import llvm;
400     import llvm_hiwrap.type.type;
401 
402     LxInstructionAllocaValue value;
403     alias value this;
404 
405     auto asValue() {
406         return Value(value);
407     }
408 
409     auto asInstr() {
410         return InstructionValue(value);
411     }
412 
413     /// Obtain the type that is being allocated by the alloca instruction.
414     Type type() {
415         return LLVMGetAllocatedType(value).LxType.Type;
416     }
417 }
418 
419 /** Functions in this group only apply to instructions that map to
420  * llvm::GetElementPtrInst instances.
421  */
422 struct InstructionElementPtrValue {
423     import llvm;
424 
425     LxInstructionElementPtrValue value;
426     alias value this;
427 
428     auto asValue() {
429         return Value(value);
430     }
431 
432     auto asInstr() {
433         return InstructionValue(value);
434     }
435 
436     /** Check whether the given GEP instruction is inbounds.
437      */
438     bool isInBounds() {
439         return LLVMIsInBounds(value) != 0;
440     }
441 
442     /** Set the given GEP instruction to be inbounds or not.
443      */
444     void setInBounds(bool onoff) {
445         LLVMSetIsInBounds(value, onoff ? 1 : 0);
446     }
447 }
448 
449 struct SuccessorsRange {
450     import llvm;
451 
452     private size_t length_;
453     private LxInstructionTerminatorValue value;
454 
455     this(InstructionTerminatorValue v) {
456         value = v;
457         length_ = LLVMGetNumSuccessors(v);
458     }
459 
460     size_t length() {
461         return length_;
462     }
463 
464     BasicBlock opIndex(size_t index) {
465         assert(index < length);
466         return LLVMGetSuccessor(value, cast(uint) index).LxBasicBlock.BasicBlock;
467     }
468 
469     import llvm_hiwrap.util;
470 
471     mixin IndexedRangeX!BasicBlock;
472 }