home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
sa104os2.zip
/
SATHR104.ZIP
/
SATHER
/
COMPILER
/
INLINE.SA
< prev
next >
Wrap
Text File
|
1994-11-15
|
10KB
|
367 lines
-- Copyright (C) International Computer Science Institute, 1994. COPYRIGHT --
-- NOTICE: This code is provided "AS IS" WITHOUT ANY WARRANTY and is subject --
-- to the terms of the SATHER LIBRARY GENERAL PUBLIC LICENSE contained in --
-- the file "Doc/License" of the Sather distribution. The license is also --
-- available from ICSI, 1947 Center St., Suite 600, Berkeley CA 94704, USA. --
--------> Please email comments to "sather-bugs@icsi.berkeley.edu". <----------
-- inline.sa: Code for inlining calls.
-------------------------------------------------------------------
type $INLINE is
-- Information about a signature to enable it to be inlined.
sig:SIG; -- The signature this is info for.
inline(call:AM_ROUT_CALL_EXPR, trans:TRANS):$AM_EXPR;
-- Return a replacement for the call `call' in the context
-- defined by `trans'. The result is a tuple, the first component
-- is a list of statments which must be executed before
-- the expression is evaluated, the second is the expression.
end;
-------------------------------------------------------------------
class INLINE_ATTR_READ < $INLINE is
-- A reference attribute read.
-- The signature has the form: "FOO::name:BAR".
shared inlined,routines:INT;
attr sig:SIG;
attr self_tp:$TP;
attr at:IDENT;
attr tp_at:$TP;
inline(call:AM_ROUT_CALL_EXPR, trans:TRANS):$AM_EXPR is
inlined:=inlined+1;
r::=#AM_ATTR_EXPR(call.source);
r.ob:=call[0];
r.self_tp:=self_tp;
r.at:=at;
r.tp_at:=tp_at;
return r;
end;
create(am:AM_ROUT_DEF):SAME is
r::=new;
r.sig:=am.sig;
stmt::=am.code;
typecase stmt when AM_RETURN_STMT then
val::=stmt.val;
typecase val when AM_ATTR_EXPR then
r.at:=val.at;
r.self_tp:=val.self_tp;
r.tp_at:=val.tp_at;
end;
end;
routines:=routines+1;
return r;
end;
end;
-------------------------------------------------------------------
class INLINE_ATTR_WRITE < $INLINE is
-- A reference attribute write.
-- The signature has the form: "FOO::name(BAR)".
shared inlined,routines:INT;
attr sig:SIG;
attr self_tp:$TP;
attr at:IDENT;
attr tp_at:$TP;
inline(call:AM_ROUT_CALL_EXPR, trans:TRANS):$AM_EXPR is
inlined:=inlined+1;
a::=#AM_ATTR_EXPR(call.source);
a.ob:=call[0];
a.self_tp:=self_tp;
a.at:=at;
a.tp_at:=tp_at;
as::=#AM_ASSIGN_STMT(call.source);
as.dest:=a;
as.src:=call[1];
r::=#AM_STMT_EXPR(call.source); r.stmts:=as; return r end;
create(am:AM_ROUT_DEF):SAME is
r::=new;
r.sig:=am.sig;
stmt::=am.code;
typecase stmt when AM_ASSIGN_STMT then
dest::=stmt.dest;
typecase dest when AM_ATTR_EXPR then
r.self_tp:=dest.self_tp;
r.at:=dest.at;
r.tp_at:=dest.tp_at;
end;
end;
routines:=routines+1;
return r;
end;
end;
-------------------------------------------------------------------
class INLINE_INT_FOLD < $INLINE is
-- Constant folding for INT::plus(INT):INT
shared inlined,routines:INT;
attr sig:SIG;
inline(call:AM_ROUT_CALL_EXPR, trans:TRANS):$AM_EXPR is
arg1::=call[0];
arg2::=call[1];
typecase arg1
when AM_INT_CONST then
typecase arg2
when AM_INT_CONST then
r::=#AM_INT_CONST(arg1.source);
r.val:=arg1.val+arg2.val;
r.tp_at:=arg1.tp_at;
-- this isn't quite right if it should
-- have overflowed.
inlined:=inlined+1;
return r;
else
end;
else
end;
return call;
end;
create(s:SIG):SAME is
r::=new;
r.sig:=s;
routines:=routines+1;
return r;
end;
end;
-------------------------------------------------------------------
class INLINE_GLOBAL_READ < $INLINE is
-- A value attribute read.
-- The signature has the form: "FOO::name:BAR".
shared inlined,routines:INT;
attr sig:SIG;
attr age:AM_GLOBAL_EXPR;
inline(call:AM_ROUT_CALL_EXPR, trans:TRANS):$AM_EXPR is
inlined:=inlined+1;
return age;
end;
create(am:AM_ROUT_DEF):SAME is
r::=new;
r.sig:=am.sig;
stmt::=am.code;
typecase stmt when AM_RETURN_STMT then
val::=stmt.val;
typecase val when AM_GLOBAL_EXPR then r.age:=val; end;
end;
routines:=routines+1;
return r;
end;
end;
-------------------------------------------------------------------
class INLINE_VATTR_READ < $INLINE is
-- A value attribute read.
-- The signature has the form: "FOO::name:BAR".
attr sig:SIG;
inline(call:AM_ROUT_CALL_EXPR, trans:TRANS):$AM_EXPR is
return call
end;
end;
-------------------------------------------------------------------
class INLINE_VATTR_WRITE < $INLINE is
-- A value attribute write.
-- The signature has the form: "FOO::name(BAR):FOO".
attr sig:SIG;
inline(call:AM_ROUT_CALL_EXPR, trans:TRANS):$AM_EXPR is
return call
end;
end;
-------------------------------------------------------------------
class INLINE_ARR_READ < $INLINE is
-- A reference array read.
-- The signature has the form: "FOO::name(ind:INT):BAR".
attr sig:SIG;
inline(call:AM_ROUT_CALL_EXPR, trans:TRANS):$AM_EXPR is
return call
end;
end;
-------------------------------------------------------------------
class INLINE_ARR_WRITE < $INLINE is
-- A reference array write.
-- The signature has the form: "FOO::name(ind:INT,val:BAR)".
attr sig:SIG;
inline(call:AM_ROUT_CALL_EXPR, trans:TRANS):$AM_EXPR is
return call
end;
end;
-------------------------------------------------------------------
class INLINE_VARR_READ < $INLINE is
-- A value array read.
-- The signature has the form: "FOO::name(ind:INT):BAR".
attr sig:SIG;
inline(call:AM_ROUT_CALL_EXPR, trans:TRANS):$AM_EXPR is
return call
end;
end;
-------------------------------------------------------------------
class INLINE_VARR_WRITE < $INLINE is
-- A value array write.
-- The signature has the form: "FOO::name(ind:INT,val:BAR):FOO".
attr sig:SIG;
inline(call:AM_ROUT_CALL_EXPR, trans:TRANS):$AM_EXPR is
return call
end;
end;
-------------------------------------------------------------------
class INLINE_BUILTIN < $INLINE is
-- A builtin routine call.
-- Any signature.
attr sig:SIG;
inline(call:AM_ROUT_CALL_EXPR, trans:TRANS):$AM_EXPR is
return call
end;
end;
-------------------------------------------------------------------
class INLINE_ROUT < $INLINE is
-- A routine which is short enough to be directly inlined.
-- Any signature.
attr am:AM_ROUT_DEF;
sig:SIG is return am.sig; end;
inline(call:AM_ROUT_CALL_EXPR, trans:TRANS):$AM_EXPR is
return call
end;
create(sig:SIG, am:AM_ROUT_DEF):SAME is r::=new; r.am:=am; return r; end;
end;
-------------------------------------------------------------------
class INLINE_TBL is
-- A table of $INLINE objects retrievable by signature.
-- Only those objects which are to be inlined are in here. If a
-- signature has been transformed and it isn't in here, then
-- it isn't inlinable.
--
-- `get_query(s:SIG):$INLINE' yields the info for the sig `s'.
-- `test($INLINE):BOOL' tests for the given $INLINE.
-- `insert($INLINE):SAME' inserts an inline.
-- `delete($INLINE):SAME' deletes an inline.
-- `elt!:ELT' yields each inline.
include FQSET{SIG,$INLINE} create->old_create;
attr prog:PROG;
create(p:PROG):SAME is
r::=old_create(1024);
r.prog:=p;
ipiis::=#SIG;
int_tp::=p.tp_builtin.int;
ipiis.tp:=int_tp;
ipiis.name:=p.ident_for("plus");
ipiis.args:=#ARRAY{$TP}(1);
ipiis.args[0]:=int_tp;
ipiis.ret:=int_tp;
ipiis.is_builtin:=true;
r:=r.insert(#INLINE_INT_FOLD(ipiis));
return r;
end;
query_test(s:SIG, in:$INLINE):BOOL is
-- True if `in' is info for the signature `s'.
if void(in) then return false end;
return in.sig=s end;
query_hash(s:SIG):INT is
-- A hash value computed from the sig `s'.
sc::=3;
r::=s.name.hash; -- Make depend on name.
r:=r.bxor(s.tp.hash*sc); -- Make depend on type
loop sc:=sc+98; r:=r.bxor(s.args.elt!.hash*sc) end; -- And on params.
return r end;
elt_hash(in:$INLINE):INT is
-- A hash value computed from the signature of `in'.
return query_hash(in.sig) end;
test_and_insert(am:AM_ROUT_DEF):SAME is
-- Test `am' for whether it should be inlinable, if it should
-- insert it into the table and return the table. If not,
-- leave the table alone.
r::=self;
if ~am.is_abstract
and ~am.is_external
and ~void(am.code) then
stmts::=am.code;
typecase stmts
when AM_RETURN_STMT then
val::=stmts.val;
typecase val
when AM_ATTR_EXPR then
if SYS::ob_eq(val.ob,am[0]) then -- must be self.
r:=r.insert(#INLINE_ATTR_READ(am));
end;
when AM_GLOBAL_EXPR then
r:=r.insert(#INLINE_GLOBAL_READ(am));
else -- don't inline
end;
when AM_ASSIGN_STMT then
dest::=stmts.dest;
src::=stmts.src;
typecase dest
when AM_ATTR_EXPR then
if SYS::ob_eq(dest.ob,am[0])
and SYS::ob_eq(src,am[1]) then
r:=r.insert(#INLINE_ATTR_WRITE(am));
end;
else -- don't inline
end;
else -- don't inline
end;
end;
return r end;
end; -- class INLINE_TBL
-------------------------------------------------------------------