⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hipe_icode.erl

📁 OTP是开放电信平台的简称
💻 ERL
📖 第 1 页 / 共 3 页
字号:
%% -*- erlang-indent-level: 2 -*-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% HiPE Intermediate Code%% ====================================================================%%  Filename : 	hipe_icode.erl%%  Module   :	hipe_icode%%  Purpose  :  Provide primops for the Icode data structure.%%  History  :	1997-? Erik Johansson (happi@csd.uu.se): Created.%%              2001-01-30 EJ (happi@csd.uu.se):%%                             Apply, primop, guardop removed%%              2003-03-15 ES (happi@acm.org):%%                             Started commenting in Edoc.%%                             Moved pretty printer to separate file.%%%% $Id$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@doc%% This module implements "Linear Icode" and Icode instructions. %%          %% <p> Icode is a simple (in that it has few instructions) imperative%% language, used as the first Intermediate Code in the HiPE compiler.%% Icode is closely related to Erlang, and Icode instructions operate%% on Erlang terms. </p>%%%% <h2><a href="#type-icode">Icode</a></h2>%%%% <p> Linear Icode for a function consists of:%%     <ul>%%       <li> the function's name (`{M,F,A}'), </li>%%       <li> a list of parameters, </li>%%       <li> a list of instructions, </li>%%       <li> data, </li>%%       <li> information about whether the function is a leaf function, </li>%%       <li> information about whether the function is a closure, and </li>%%       <li> the range for labels and variables in the code. </li>%%     </ul>%% </p>%%%% <h2><a href="#type-icode_instruction">Icode Instructions</a> (and%% their components)</h2>%%%% Control flow:%% <dl>%%    <dt><code><a href="#type-if">'if'</a> %%          {Cond::<a href="#type-cond">cond()</a>, %%           Args::[<a href="#type-arg">arg()</a>],%%           TrueLabel::<a href="#type-label_name">label_name()</a>, %%           FalseLabel::<a href="#type-label_name">label_name()</a>%%          } :: %%           <a href="#type-icode_instruction">icode_instruction()</a></code></dt>%%    <dd>%%        The if instruction compares the arguments (Args) with%%        condition (Cond) and jumps to either TrueLabel or%%        FalseLabel. (At the moment...) There are only binary%%        conditions so the number of arguments should be two.%%        <p>%%        An if instructions ends a basic block and should be followed%%        by a label (or be the last instruction of the code).%%        </p></dd>%%%%    <dt><code><a href="#type-switch_val">switch_val</a> %%                    {Arg::<a href="#type-arg">arg()</a>, %%                     FailLabel::<a href="#type-label_name">label_name()</a>, %%                     Length::integer(), %%                     Cases::[{<a href="#type-symbol">symbol()</a>,<a%%                     href="#type-label_name">label_name()</a>}] %% }::%%           <a href="#type-icode_instruction">icode_instruction()</a></code></dt>%%    <dd>%%        The switch_val instruction compares the argument Arg to the%%        symbols in the lists Cases, control is transfered to the label%%        that corresponds to the first symbol that matches.  If no%%        symbol matches control is transfered to FailLabel.  (NOTE: The%%        length argument is not currently in use.)%%        <p>%%        The switch_val instruction can be assumed to be implemented as%%        efficiently as possible given the symbols in the case%%        list. (Jump-table, bianry-serach, or nested ifs)%%        </p><p>%%        A switch_val instructions ends a basic block and should be%%        followed by a label (or be the last instruction of the code).%%        </p></dd>%%%%    <dt><code><a href="#type-switch_tuple_arity">switch_tuple_arity</a>%%         {%%          Arg::<a href="#type-arg">arg()</a>, %%          FailLabel::<a href="#type-label_name">label_name()</a>, %%          Length::integer(),  %%          Cases::[{integer(),<a href="#type-label_name">label_name()</a>}]%%        }::%%           <a href="#type-icode_instruction">icode_instruction()</a></code></dt>%%    <dd>%%        The switch_tuple_arity instruction compares the size of the%%        tuple in the argument Arg to the integers in the lists Cases,%%        control is transfered to the label that corresponds to the%%        first integer that matches.  If no integer matches control is%%        transfered to FailLabel.  (NOTE: The length argument is not%%        currently in use.)%%        <p>%%        The switch_tuple_arity instruction can be assumed to be%%        implemented as efficently as possible given the symbols in the%%        case list. (Jump-table, bianry-serach, or nested ifs)%%        </p><p>%%        A switch_tuple_arity instructions ends a basic block and%%        should be followed by a label (or be the last instruction of%%        the code).%%        </p></dd>%%%%    <dt>`type {typ_expr, arg, true_label, false_label}}'</dt>%%    <dt>`goto {label}'</dt>%%    <dt>`label {name}'</dt>%% </dl>%%%% Moves:%% <dl>%%    <dt>`move {dst, src}'</dt>%%    <dt>`fmove {dst, src}'</dt>%%    <dt>`phi {dst, arglist}'</dt>%% </dl>%%%% Function application:%% <dl>%%    <dt>`call {[dst], fun, [arg], type, continuation, fail,%%               in_guard}'</dt>%%    <dd>%%        Where `type' is one of {`local', `remote', `primop'}%%        and `in_guard' is either `true' or `false'.</dd>%%    <dt>`enter {fun, [arg], type}'</dt>%%    <dd>%%        Where `type' is one of {`local', `remote', `primop'}%%         and `in_guard' is either `true' or `false'.</dd>%%    <dt>`return {[var]}'</dt>%%    <dd>%%        <strong>WARNING:</strong> Multiple return values are yet not%%        fully implemented and tested.%%    </dd>%% </dl>%%%% Error handling:%% <dl>%%    <dt>`begin_try {label, successor}'</dt>%%    <dt>`end_try'</dt>%%    <dt>`begin_handler {dstlist}'</dt>%%    <dt>`fail {Args, Class}'</dt>%%    <dd>Where `Class' is one of %%      {`exit', `throw', `error', `rethrow'}. For `error/2', `[args]'%%      is `[Reason,Trace]'. For `rethrow', `Args' is%%      `[Exception,Reason]' - this only occurs in autogenerated code.%%    </dd>%% </dl>%%%% Comments:%% <dl>%%    <dt>`comment{Text::string()}'</dt>%% </dl>%%%% <h4>Notes</h4>%%%%  <p> A constant can only show up on the RHS of a `move' instruction%%      and in `if' and `switch_*'</p>%%  <p>%%      Classification of primops should be like this:%%      <ul>%%      <li> `erlang:exit/1, erlang:throw/1, erlang:error/1,%%            erlang:error/2, erlang:fault/1',%%           and `erlang:fault/2' should use the%%           {@link fail(). fail-instruction} in Icode.</li>%%      <li> Calls or tail-recursive calls to BIFs, operators, or internal%%           functions should be implemented with `call' or `enter' %%           respectively, with the primop flag set.</li>%%      <li> All other Erlang functions should be implemented with `call'%%           or `enter' respectively, without the primop flag set.</li>%%      </ul>%%  </p>%%%% <h4>Primops</h4>%%%% <pre>%%  Constructors:%%    cons                       - [Car, Cdr]%%    mktuple                    - [Element1, Element2, ..., ElementN]%%    call_fun                   - [BoundArg1, ..., BoundArgN, Fun]%%    enter_fun                  - [BoundArg1, ..., BoundArgN, Fun]%%    #mkfun{}                   - [FreeVar1, FreeVar2, ..., FreeVarN]%%%%  Binaries:%%    bs_init%%    {bs_put_string, Bytes, Size}%%    bs_final%%%%  Selectors:%%    element                    - [Index, Tuple]%%    unsafe_hd                  - [List]%%    unsafe_tl                  - [List]%%    #unsafe_element{}          - [Tuple]%%    #unsafe_update_element{}   - [Tuple, Val]%%    #closure_element{}         - [Fun]%%%%  Arithmetic:       [Arg1, Arg2]%%    '+', '-', '*', '/', 'div', 'rem',%%    'band', 'bor', 'bxor', 'bnot', 'bsl', 'bsr'%%%%  Receive:         %%    check_get_msg - []%%    next_msg      - []%%    select_msg    - []%%    set_timeout   - [Timeout]%%    clear_timeout - []%%    suspend_msg   - []%%%% </pre>%%%% <h4>Guardops: (primops that can be used in guards and can fail)</h4>%%  <pre>%%  Selectors:%%    unsafe_hd         - [List]%%    unsafe_tl         - [List]%%    #element{}        - [Index, Tuple]%%    #unsafe_element{} - [Tuple]%%%%  Arithmetic:       [Arg1, Arg2]%%    '+', '-', '*', '/', 'div', 'rem',%%   'band', 'bor', 'bxor', 'bnot', 'bsl', 'bsr',%%    fix_add, fix_sub               %% Do these exist?%%%%  Concurrency:%%    {erlang,self,0}          - []%% </pre>%%%%%% <h4>Relational Operations (Cond in if instruction)</h4>%% <pre>%%    gt, lt, geq, leq,%%    eqeq, neq, exact_eqeq, exact_neq%% </pre>%%%% <h4>Type tests</h4>%% <pre>%%    list%%    nil%%    cons%%    tuple%%    {tuple, N}%%    atom%%    {atom, Atom}%%    constant%%    number%%    integer%%    {integer, N}%%    fixnum%%    bignum%%    float%%    pid%%    port%%    {record, Atom, Size}%%    reference%%    binary%%    function%% </pre>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%=====================================================================-module(hipe_icode).-include("../main/hipe.hrl").-include("hipe_icode.hrl").%% @type icode(Fun, Params, IsClosure, IsLeaf, Code, Data, VarRange,LabelRange)%%    Fun = mfa()%%    Params = [var()]%%    IsClosure = bool()%%    IsLeaf = bool()%%    Code = [icode_instruction()]%%    Data = data()%%    VarRange = {integer(),integer()}%%    LabelRange = {integer(),integer()}%%%% @type icode_instruction(I) %%    I = if() | switch_val() | switch_tuple_arity() | type() | goto()%%      | label() | move() | fmove() | phi() | call() | enter() | return() %%      | begin_try() | end_try() | begin_handler() | fail() | comment()%%%% @type if(Cond, Args, TrueLabel, FalseLabel)%%    Cond = cond()%%    Args = [arg()]%%    TrueLabel = label_name()%%    FalseLabel = label_name()%%%% @type switch_val(Arg, FailLabel, Length, Cases) %%    Arg = arg()%%    FailLabel=label_name()%%    Length = integer()%%    Cases = [{symbol(),label_name()}]%%%% @type switch_tuple_arity(Arg, FailLabel, Length, Cases)%%    Arg = arg()%%    FailLabel = label_name()%%    Length = integer()%%    Cases = [{symbol(), label_name()}]%%%% @type type(TypeExpr, Arg, True_label, False_label)%%    TypeExpr = type_type()%%    Args = [arg()]%%    TrueLabel = label_name()%%    FalseLabel = label_name()%%%% @type goto(Label) Label = label_name()%%%% @type label(Name) Name = label_name()%%%% @type move(Dst, Src) Dst = var() Src = arg()%%%% @type fmove(Dst, Src) Dst = fvar() Src = farg()%%%% @type phi(Dst, Id, Arglist) %%    Dst = var() | fvar()%%    Id = var() | fvar()%%    Arglist = [{Pred, Src}]%%    Pred = label_name()%%    Src = var() | fvar() %%%% @type call(Dst, Fun, Arg, Type, Continuation, InGuard)%%    Dst = [var()]%%    Fun = mfa() | primop() | closure() %%    Arg = [var()]%%    Type = call_type()%%    Continuation = [] | label_name()%%    Fail = [] | label_name()%%    InGuard = bool()%%%% @type enter(Fun, Arg, Type)%%    Fun = mfa() | primop() | closure() %%    Arg = [var()] %%    Type = call_type()%%%% @type return (Vars) Vars = [var()]%%%% @type begin_try(Fail, Successor) %%    Fail = label_name()%%    Successor = label_name()%%%% @type end_try()%%%% @type begin_handler(Dst) %%    Dst = [var()]%%%% @type fail(Args,Class,Label)%%    Args = [var()]%%    Class = exit_class()%%    Label = label_name()%%%% @type comment(Text) Text = string()%% @type call_type()  = 'local' | 'remote' | 'primop'%% @type exit_class() = 'exit' | 'throw' | 'error' | 'rethrow'%% @type cond() = gt | lt | geq | leq | eqeq | neq | exact_eqeq | exact_neq%% @type type_type() = %%      list%%    | nil%%    | cons%%    | tuple%%    | {tuple, integer()}%%    | atom%%    | {atom, atom()}%%    | constant%%    | number%%    | integer%%    | {integer, integer()}%%    | fixnum%%    | bignum%%    | float%%    | pid%%    | port%%    | {record, atom(), integer()}%%    | reference%%    | binary%%    | function%%%% @type mfa(Mod,Fun,Arity) = {atom(),atom(),byte()}%% @type arg() = var() | const()%% @type farg() = fvar() | float()%% @type var(Name) Name = integer()%% @type fvar(Name) Name = integer()%% @type label_name(Name) Name = integer()%% @type symbol(S) = atom() | number()%% @type const(C)  C = const_fun() | immediate()%% @type const_fun(MFA,U,I,Args) = {MFA,U,I,Args}%%    MFA = mfa()%%    U = integer()%%    I = integer()%%    Args = [var()]%% @type immediate(I) = I%%    I = term()%% @end%% ____________________________________________________________________%%%% Exports%%-export([mk_icode/7, %% mk_icode(Fun, Params, IsClosure, IsLeaf, 		     %%          Code, VarRange, LabelRange)	 mk_icode/8, %% mk_icode(Fun, Params, IsClosure, IsLeaf, 		     %%          Code, Data, VarRange, LabelRange)	 mk_typed_icode/8,	 icode_fun/1,	 icode_params/1,	 icode_params_update/2,	 icode_is_closure/1,	 icode_closure_arity/1,	 icode_closure_arity_update/2,	 icode_is_leaf/1,	 icode_code/1,	 icode_code_update/2,	 icode_data/1,	 %% icode_data_update/2,	 icode_var_range/1,	 icode_label_range/1,	 icode_info/1,	 icode_info_update/2]).-export([mk_if/4,           %% mk_if(Op, Args, TrueLbl, FalseLbl)	 %% mk_if/5,	    %% mk_if(Op, Args, TrueLbl, FalseLbl, Prob)	 if_op/1,	 if_op_update/2,	 if_true_label/1,	 if_false_label/1,	 if_args/1,	 if_pred/1,	 %% is_if/1,	 	 mk_switch_val/4,	 %% mk_switch_val/5,	 switch_val_arg/1,	 switch_val_fail_label/1,		 %% switch_val_length/1,	 switch_val_cases/1,	 switch_val_cases_update/2,	 %% is_switch_val/1,	 	 mk_switch_tuple_arity/4,	 %% mk_switch_tuple_arityl/5,	 switch_tuple_arity_arg/1,	 switch_tuple_arity_fail_label/1,	 switch_tuple_arity_fail_label_update/2,	 %% switch_tuple_arity_length/1,	 switch_tuple_arity_cases/1,	 switch_tuple_arity_cases_update/2,	 %% is_switch_tuple_arity/1,	 mk_type/4,        %% mk_type(Args, Type, TrueLbl, FalseLbl)	 mk_type/5,	   %% mk_type(Args, Type, TrueLbl, FalseLbl, P)	 type_args/1,	 %% type_args_update/2,	 type_type/1,	 type_true_label/1,	 type_false_label/1,	 type_pred/1,	 is_type/1,	 mk_guardop/5,     %% mk_guardop(Dst, Fun, Args, Continuation, Fail)	 mk_primop/3,      %% mk_primop(Dst, Fun, Args)	 mk_primop/5,      %% mk_primop(Dst, Fun, Args, Cont, Fail)	 mk_typed_call/6,  %% mk_call(Dst, Mod, Fun, Args, Type, DstType)	 mk_call/5,	   %% mk_call(Dst, Mod, Fun, Args, Type)	 %% mk_call/7,	   %% mk_call(Dst, Mod, Fun, Args, Type,	                   %%         Continuation, Fail)	 mk_call/8,	   %% mk_call(Dst, Mod, Fun, Args, Type,	                   %%         Continuation, Fail, Guard)	 call_dstlist/1,	 call_dstlist_update/2,	 call_dst_type/1,	 call_args/1,	 call_args_update/2,	 call_fun/1,	 call_fun_update/2,	 call_type/1,	 call_continuation/1,	 call_fail_label/1,	 call_set_fail_label/2,	 call_set_continuation/2,	 is_call/1, 	 call_in_guard/1,	 mk_goto/1,              %% mk_goto(Lbl)	 goto_label/1,	 	 mk_enter/4,             %% mk_enter(Mod, Fun, Args, Type)	 mk_enter_primop/2,      %% mk_enter_primop(Op, Type)	 enter_fun/1,	 enter_fun_update/2,	 enter_args/1,	 enter_args_update/2,	 enter_type/1,	 is_enter/1,	 	 mk_fmove/2,             %% mk_fmove(Dst, Src)	 mk_return/1,            %% mk_return(Vars)	 %% mk_fail/1,	         %% mk_fail(Args) class = exit	 mk_fail/2,              %% mk_fail(Args, Class)	 %% mk_fail/3,           %% mk_fail(Args, Class, Label)	 mk_move/2,              %% mk_move(Dst, Src)	 mk_moves/2,             %% mk_moves(DstList, SrcList)	 mk_begin_try/2,         %% mk_begin_try(Label, Successor)	 mk_begin_handler/1,     %% mk_begin_handler(ReasonDst)	 mk_end_try/0,           %% mk_end_try()	 %% mk_elements/2,       %% mk_elements(Tuple, Vars)	 mk_label/1,             %% mk_label(Name)	 mk_new_label/0,         %% mk_new_label()	 mk_comment/1,           %% mk_comment(Text)	 mk_const/1,             %% mk_const(Const)	 %% mk_const_fun/4,	 %% mk_const_fun(MFA, U, I, Args)	 mk_var/1,               %% mk_var(Id)	 annotate_var/2,         %% annotate_var(Var, Type)	 unannotate_var/1,	 %% unannotate_var(Var)	 mk_reg/1,               %% mk_reg(Id)	 mk_fvar/1,              %% mk_fvar(Id)	 mk_new_var/0,           %% mk_new_var()	 mk_new_fvar/0,          %% mk_new_fvar()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -