diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-09-30 02:21:21 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-09-30 02:21:21 -0400 |
| commit | 4e2fa2d15be248c29051a58995e38caa0b1de0a5 (patch) | |
| tree | b8f27f8f3157b1897cf796c6b0241dafacbfd7b0 /src/ir.hpp | |
| parent | 0562111b0208d94852928f4bc7a7f2b8e335366f (diff) | |
| download | zig-4e2fa2d15be248c29051a58995e38caa0b1de0a5.tar.gz zig-4e2fa2d15be248c29051a58995e38caa0b1de0a5.zip | |
*WIP*
Diffstat (limited to 'src/ir.hpp')
| -rw-r--r-- | src/ir.hpp | 153 |
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 |
