aboutsummaryrefslogtreecommitdiff
path: root/src/ir.hpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-09-30 02:21:21 -0400
committerAndrew Kelley <superjoe30@gmail.com>2016-09-30 02:21:21 -0400
commit4e2fa2d15be248c29051a58995e38caa0b1de0a5 (patch)
treeb8f27f8f3157b1897cf796c6b0241dafacbfd7b0 /src/ir.hpp
parent0562111b0208d94852928f4bc7a7f2b8e335366f (diff)
downloadzig-4e2fa2d15be248c29051a58995e38caa0b1de0a5.tar.gz
zig-4e2fa2d15be248c29051a58995e38caa0b1de0a5.zip
*WIP*
Diffstat (limited to 'src/ir.hpp')
-rw-r--r--src/ir.hpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/ir.hpp b/src/ir.hpp
new file mode 100644
index 0000000000..8b7df5c95d
--- /dev/null
+++ b/src/ir.hpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2016 Andrew Kelley
+ *
+ * This file is part of zig, which is MIT licensed.
+ * See http://opensource.org/licenses/MIT
+ */
+
+#ifndef ZIG_IR_HPP
+#define ZIG_IR_HPP
+
+#include "all_types.hpp"
+
+struct IrInstruction;
+
+// A basic block contains no branching. Branches send control flow
+// to another basic block.
+// Phi instructions must be first in a basic block.
+// The last instruction in a basic block must be an expression of type unreachable.
+struct IrBasicBlock {
+ ZigList<IrInstruction *> instructions;
+};
+
+enum IrInstructionId {
+ IrInstructionIdCondBr,
+ IrInstructionIdSwitchBr,
+ IrInstructionIdPhi,
+ IrInstructionIdAdd,
+ IrInstructionIdBinOp,
+ IrInstructionIdLoadVar,
+ IrInstructionIdStoreVar,
+ IrInstructionIdCall,
+ IrInstructionIdBuiltinCall,
+ IrInstructionIdConst,
+ IrInstructionIdReturn,
+};
+
+struct IrInstruction {
+ IrInstructionId id;
+ AstNode *source_node;
+ ConstExprValue static_value;
+ TypeTableEntry *type_entry;
+};
+
+struct IrInstructionCondBr {
+ IrInstruction base;
+
+ // If the condition is null, then this is an unconditional branch.
+ IrInstruction *cond;
+ IrBasicBlock *dest;
+};
+
+struct IrInstructionSwitchBrCase {
+ IrInstruction *value;
+ IrBasicBlock *block;
+};
+
+struct IrInstructionSwitchBr {
+ IrInstruction base;
+
+ IrInstruction *target_value;
+ IrBasicBlock *else_block;
+ size_t case_count;
+ IrInstructionSwitchBrCase *cases;
+};
+
+struct IrInstructionPhi {
+ IrInstruction base;
+
+ size_t incoming_block_count;
+ IrBasicBlock **incoming_blocks;
+ IrInstruction **incoming_values;
+};
+
+enum IrBinOp {
+ IrBinOpInvalid,
+ IrBinOpBoolOr,
+ IrBinOpBoolAnd,
+ IrBinOpCmpEq,
+ IrBinOpCmpNotEq,
+ IrBinOpCmpLessThan,
+ IrBinOpCmpGreaterThan,
+ IrBinOpCmpLessOrEq,
+ IrBinOpCmpGreaterOrEq,
+ IrBinOpBinOr,
+ IrBinOpBinXor,
+ IrBinOpBinAnd,
+ IrBinOpBitShiftLeft,
+ IrBinOpBitShiftLeftWrap,
+ IrBinOpBitShiftRight,
+ IrBinOpAdd,
+ IrBinOpAddWrap,
+ IrBinOpSub,
+ IrBinOpSubWrap,
+ IrBinOpMult,
+ IrBinOpMultWrap,
+ IrBinOpDiv,
+ IrBinOpMod,
+ IrBinOpArrayCat,
+ IrBinOpArrayMult,
+};
+
+struct IrInstructionBinOp {
+ IrInstruction base;
+
+ IrInstruction *op1;
+ IrBinOp op_id;
+ IrInstruction *op2;
+};
+
+struct IrInstructionLoadVar {
+ IrInstruction base;
+
+ VariableTableEntry *var;
+};
+
+struct IrInstructionStoreVar {
+ IrInstruction base;
+
+ IrInstruction *value;
+ VariableTableEntry *var;
+};
+
+struct IrInstructionCall {
+ IrInstruction base;
+
+ IrInstruction *fn;
+ size_t arg_count;
+ IrInstruction **args;
+};
+
+struct IrInstructionBuiltinCall {
+ IrInstruction base;
+
+ BuiltinFnId fn_id;
+ size_t arg_count;
+ IrInstruction **args;
+};
+
+struct IrInstructionConst {
+ IrInstruction base;
+};
+
+struct IrInstructionReturn {
+ IrInstruction base;
+
+ IrInstruction *value;
+};
+
+IrBasicBlock *ir_gen(CodeGen *g, AstNode *fn_def_node, TypeTableEntry *return_type);
+TypeTableEntry *ir_analyze(CodeGen *g, AstNode *fn_def_node, IrBasicBlock *entry_basic_block,
+ TypeTableEntry *expected_type);
+
+#endif