[m-rev.] for review: fix .maxstack output and update IL instruction set

Tyson Dowd trd at cs.mu.OZ.AU
Mon May 28 01:19:35 AEST 2001


Hi,

It was annoying me that sample code I was generating for the .NET paper
had hard-coded nasty magic numbers in it...

===================================================================


Estimated hours taken: 2
Branches: main

Fix the hard-coding of .maxstack directives in the .NET backend.
We now generate the correct number by traversing the instruction set and
looking for the maximum stack depth, rather than just assuming 100 will be
large enough.

compiler/ilds.m:
	Add code to calculate the maximum stack depth.
	Also fix some missing instructions in the instruction set, and
	remove some unused instructions.  The instruction set is now
	up-to-date with the documentation at around October 2000.

compiler/il_peephole.m:
compiler/ilasm.m:
	Handle the changes to the instruction set.

compiler/mlds_to_il.m:
	Calculate maxstack instead of hard-coding it.


Index: compiler/il_peephole.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/il_peephole.m,v
retrieving revision 1.2
diff -u -r1.2 il_peephole.m
--- compiler/il_peephole.m	2001/03/16 04:17:46	1.2
+++ compiler/il_peephole.m	2001/05/27 14:31:15
@@ -425,7 +425,6 @@
 can_call(calli(_)) 				= yes.
 can_call(callvirt(_)) 				= yes.
 can_call(jmp(_)) 				= yes.
-can_call(jmpi) 					= yes.
 can_call(newobj(_))			 	= yes.
 
 can_call(comment(_Comment)) 			= no. 
@@ -435,16 +434,12 @@
 can_call(context(_, _)) 			= no.
 can_call(ret) 					= no. 
 can_call((and)) 				= no. 
-can_call(ann_catch) 				= no. 
-can_call(ann_def) 				= no. 
-can_call(ann_lab) 				= no. 
 can_call(arglist) 				= no. 
 can_call(break) 				= no. 
 can_call(ceq) 					= no. 
 can_call(ckfinite) 				= no. 
 can_call(cpblk) 				= no. 
 can_call(dup) 					= no.
-can_call(endcatch) 				= no.
 can_call(endfilter) 				= no. 
 can_call(endfinally) 				= no. 
 can_call(initblk) 				= no. 
@@ -459,11 +454,8 @@
 can_call(tailcall) 				= no. 
 can_call(volatile) 				= no. 
 can_call(xor) 					= no. 
-can_call(entercrit) 				= no. 
-can_call(exitcrit) 				= no.
 can_call(ldlen) 				= no. 
 can_call(throw)	 				= no. 
-can_call(ann_hoisted_call) 			= no.
 can_call(ldarg(_)) 				= no. 
 can_call(ldc(_Type, _Const)) 			= no.
 can_call(ldstr(_String)) 			= no. 
@@ -506,25 +498,21 @@
 can_call(ldfld(_FieldRef)) 			= no.
 can_call(ldflda(_FieldRef)) 			= no.
 can_call(ldobj(_Type)) 				= no.
-can_call(ldrefany(_Index)) 			= no.
 can_call(ldsfld(_FieldRef)) 			= no. 
 can_call(ldsflda(_FieldRef)) 			= no. 
 can_call(ldtoken(_)) 				= no.
 can_call(ldvirtftn(_MethodRef)) 		= no.
 can_call(mkrefany(_Type)) 			= no.
 can_call(newarr(_Type)) 			= no. 
+can_call(refanytype)	 			= no. 
+can_call(refanyval(_)) 				= no. 
+can_call(rethrow) 				= no. 
+can_call(sizeof(_Type))				= no. 
+can_call(stobj(_Type)) 				= no. 
 can_call(stelem(_SimpleType)) 			= no. 
 can_call(stfld(_FieldRef)) 			= no. 
 can_call(stsfld(_FieldRef)) 			= no. 
-can_call(typerefany(_Index)) 			= no.
 can_call(unbox(_Type)) 				= no.
-can_call(ann_call(_)) 				= no.
-can_call(ann_data(_)) 				= no.
-can_call(ann_dead(_)) 				= no.
-can_call(ann_hoisted(_)) 			= no.
-can_call(ann_live(_)) 				= no.
-can_call(ann_phi(_)) 				= no.
-can_call(ann_ref(_)) 				= no.
 
 	% These instructions generate no actual code and do not affect
 	% control flow, they are simply part of instr for
@@ -546,20 +534,15 @@
 equivalent_to_nop(callvirt(_MethodRef)) 		= no. 
 equivalent_to_nop(ret) 					= no. 
 equivalent_to_nop((and)) 				= no. 
-equivalent_to_nop(ann_catch) 				= no. 
-equivalent_to_nop(ann_def) 				= no. 
-equivalent_to_nop(ann_lab) 				= no. 
 equivalent_to_nop(arglist) 				= no. 
 equivalent_to_nop(break) 				= no. 
 equivalent_to_nop(ceq) 					= no. 
 equivalent_to_nop(ckfinite) 				= no. 
 equivalent_to_nop(cpblk) 				= no. 
 equivalent_to_nop(dup) 					= no.
-equivalent_to_nop(endcatch) 				= no.
 equivalent_to_nop(endfilter) 				= no. 
 equivalent_to_nop(endfinally) 				= no. 
 equivalent_to_nop(initblk) 				= no. 
-equivalent_to_nop(jmpi) 				= no. 
 equivalent_to_nop(ldnull) 				= no. 
 equivalent_to_nop(localloc)	 			= no. 
 equivalent_to_nop(neg) 					= no. 
@@ -570,11 +553,8 @@
 equivalent_to_nop(tailcall) 				= no. 
 equivalent_to_nop(volatile) 				= no. 
 equivalent_to_nop(xor) 					= no. 
-equivalent_to_nop(entercrit) 				= no. 
-equivalent_to_nop(exitcrit) 				= no.
 equivalent_to_nop(ldlen) 				= no. 
 equivalent_to_nop(throw) 				= no. 
-equivalent_to_nop(ann_hoisted_call) 			= no.
 equivalent_to_nop(ldarg(_)) 				= no. 
 equivalent_to_nop(ldc(_Type, _Const)) 			= no.
 equivalent_to_nop(ldstr(_String)) 			= no. 
@@ -618,7 +598,6 @@
 equivalent_to_nop(ldfld(_FieldRef)) 			= no.
 equivalent_to_nop(ldflda(_FieldRef)) 			= no.
 equivalent_to_nop(ldobj(_Type)) 			= no.
-equivalent_to_nop(ldrefany(_Index)) 			= no.
 equivalent_to_nop(ldsfld(_FieldRef)) 			= no. 
 equivalent_to_nop(ldsflda(_FieldRef)) 			= no. 
 equivalent_to_nop(ldtoken(_)) 				= no.
@@ -626,18 +605,15 @@
 equivalent_to_nop(mkrefany(_Type)) 			= no.
 equivalent_to_nop(newarr(_Type)) 			= no. 
 equivalent_to_nop(newobj(_MethodRef)) 			= no. 
+equivalent_to_nop(refanytype)				= no.
+equivalent_to_nop(refanyval(_))				= no.
+equivalent_to_nop(rethrow)				= no.
 equivalent_to_nop(stelem(_SimpleType)) 			= no. 
 equivalent_to_nop(stfld(_FieldRef)) 			= no. 
+equivalent_to_nop(sizeof(_Type))			= no. 
+equivalent_to_nop(stobj(_))				= no.
 equivalent_to_nop(stsfld(_FieldRef)) 			= no. 
-equivalent_to_nop(typerefany(_Index)) 			= no.
 equivalent_to_nop(unbox(_Type)) 			= no.
-equivalent_to_nop(ann_call(_)) 				= no.
-equivalent_to_nop(ann_data(_)) 				= no.
-equivalent_to_nop(ann_dead(_)) 				= no.
-equivalent_to_nop(ann_hoisted(_)) 			= no.
-equivalent_to_nop(ann_live(_)) 				= no.
-equivalent_to_nop(ann_phi(_)) 				= no.
-equivalent_to_nop(ann_ref(_)) 				= no.
 
 
 	% These instructions can branch control flow.
@@ -664,20 +640,15 @@
 can_branch(callvirt(_MethodRef)) 			= no. 
 can_branch(ret) 					= no. 
 can_branch((and)) 					= no. 
-can_branch(ann_catch) 					= no. 
-can_branch(ann_def) 					= no. 
-can_branch(ann_lab) 					= no. 
 can_branch(arglist) 					= no. 
 can_branch(break) 					= no. 
 can_branch(ceq) 					= no. 
 can_branch(ckfinite) 					= no. 
 can_branch(cpblk) 					= no. 
 can_branch(dup) 					= no.
-can_branch(endcatch) 					= no.
 can_branch(endfilter) 					= no. 
 can_branch(endfinally) 					= no. 
 can_branch(initblk) 					= no. 
-can_branch(jmpi) 					= no. 
 can_branch(ldnull) 					= no. 
 can_branch(localloc)		 			= no. 
 can_branch(neg) 					= no. 
@@ -688,11 +659,8 @@
 can_branch(tailcall) 					= no. 
 can_branch(volatile) 					= no. 
 can_branch(xor) 					= no. 
-can_branch(entercrit) 					= no. 
-can_branch(exitcrit) 					= no.
 can_branch(ldlen) 					= no. 
 can_branch(throw) 					= no. 
-can_branch(ann_hoisted_call) 				= no.
 can_branch(ldarg(_)) 					= no. 
 can_branch(ldc(_Type, _Const)) 				= no.
 can_branch(ldstr(_String)) 				= no. 
@@ -726,7 +694,6 @@
 can_branch(ldfld(_FieldRef)) 				= no.
 can_branch(ldflda(_FieldRef)) 				= no.
 can_branch(ldobj(_Type)) 				= no.
-can_branch(ldrefany(_Index)) 				= no.
 can_branch(ldsfld(_FieldRef)) 				= no. 
 can_branch(ldsflda(_FieldRef)) 				= no. 
 can_branch(ldtoken(_)) 					= no.
@@ -734,16 +701,13 @@
 can_branch(mkrefany(_Type)) 				= no.
 can_branch(newarr(_Type)) 				= no. 
 can_branch(newobj(_MethodRef)) 				= no. 
+can_branch(rethrow) 					= no. 
+can_branch(refanytype) 					= no. 
+can_branch(refanyval(_)) 				= no. 
 can_branch(stelem(_SimpleType)) 			= no. 
 can_branch(stfld(_FieldRef)) 				= no. 
+can_branch(stobj(_)) 					= no. 
+can_branch(sizeof(_Type))				= no. 
 can_branch(stsfld(_FieldRef)) 				= no. 
-can_branch(typerefany(_Index)) 				= no.
 can_branch(unbox(_Type)) 				= no.
-can_branch(ann_call(_)) 				= no.
-can_branch(ann_data(_)) 				= no.
-can_branch(ann_dead(_)) 				= no.
-can_branch(ann_hoisted(_)) 				= no.
-can_branch(ann_live(_)) 				= no.
-can_branch(ann_phi(_)) 					= no.
-can_branch(ann_ref(_)) 					= no.
 
Index: compiler/ilasm.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ilasm.m,v
retrieving revision 1.9
diff -u -r1.9 ilasm.m
--- compiler/ilasm.m	2001/05/02 16:34:36	1.9
+++ compiler/ilasm.m	2001/05/27 14:31:15
@@ -873,12 +873,6 @@
 	io__write_string("ret").
 output_instr((and), I, I) --> 
 	io__write_string("and").
-output_instr(ann_catch, I, I) --> 
-	io__write_string("ann_catch").
-output_instr(ann_def, I, I) --> 
-	io__write_string("ann_def").
-output_instr(ann_lab, I, I) --> 
-	io__write_string("ann_lab").
 output_instr(arglist, I, I) --> 
 	io__write_string("arglist").
 output_instr(break, I, I) --> 
@@ -891,16 +885,12 @@
 	io__write_string("cpblk").
 output_instr(dup, I, I) -->
 	io__write_string("dup").
-output_instr(endcatch, I, I) -->
-	io__write_string("endcatch").
 output_instr(endfilter, I, I) --> 
 	io__write_string("endfilter").
 output_instr(endfinally, I, I) --> 
 	io__write_string("endfinally").
 output_instr(initblk, I, I) --> 
 	io__write_string("initblk").
-output_instr(jmpi, I, I) --> 
-	io__write_string("jmpi").
 output_instr(ldnull, I, I) --> 
 	io__write_string("ldnull").
 output_instr(localloc, I, I) --> 
@@ -923,16 +913,10 @@
 	io__write_string("volatile").
 output_instr(xor, I, I) --> 
 	io__write_string("xor").
-output_instr(entercrit, I, I) --> 
-	io__write_string("entercrit").
-output_instr(exitcrit, I, I) -->
-	io__write_string("exitcrit").
 output_instr(ldlen, I, I) --> 
 	io__write_string("ldlen").
 output_instr(throw, I, I) --> 
 	io__write_string("throw").
-output_instr(ann_hoisted_call, I, I) -->
-	io__write_string("ann_hoisted_call").
 
 	% There are short forms of various instructions.
 	% The assembler can't generate them for you.
@@ -1176,10 +1160,6 @@
 output_instr(ldobj(Type), Info0, Info) -->
 	io__write_string("ldobj\t"),
 	output_type(Type, Info0, Info).
-	
-output_instr(ldrefany(Index), I, I) -->
-	io__write_string("ldrefany\t"),
-	output_index(Index).
 
 output_instr(ldsfld(FieldRef), Info0, Info) --> 
 	io__write_string("ldsfld\t"),
@@ -1208,6 +1188,16 @@
 	io__write_string("newobj\t"),
 	output_methodref(MethodRef, Info0, Info).
 
+output_instr(refanytype, I, I) --> 
+	io__write_string("refanytype").
+
+output_instr(refanyval(Type), Info0, Info) --> 
+	io__write_string("refanyval\t"),
+	output_type(Type, Info0, Info).
+
+output_instr(rethrow, I, I) --> 
+	io__write_string("rethrow").
+
 output_instr(stelem(SimpleType), I, I) --> 
 	io__write_string("stelem."),
 	output_simple_type_opcode(SimpleType).
@@ -1216,29 +1206,22 @@
 	io__write_string("stfld\t"),
 	output_fieldref(FieldRef, Info0, Info).
 
+output_instr(stobj(Type), Info0, Info) -->
+	io__write_string("stobj\t"),
+	output_type(Type, Info0, Info).
+	
+output_instr(sizeof(Type), Info0, Info) -->
+	io__write_string("sizeof\t"),
+	output_type(Type, Info0, Info).
+
 output_instr(stsfld(FieldRef), Info0, Info) --> 
 	io__write_string("stsfld\t"),
 	output_fieldref(FieldRef, Info0, Info).
 
-output_instr(typerefany(Index), I, I) -->
-	io__write_string("typerefany\t"),
-	output_index(Index).
-
 output_instr(unbox(Type), Info0, Info) -->
 	io__write_string("unbox\t"),
 	output_type(Type, Info0, Info).
 
-	% This is stuff for "Opt-IL", which was (is?) some sort of 
-	% optimization annotated IL.  I have no idea whether it is used
-	% at all.
-output_instr(ann_call(_), I, I) --> { error("output not implemented") }.
-output_instr(ann_data(_), I, I) --> { error("output not implemented") }.
-output_instr(ann_dead(_), I, I) --> { error("output not implemented") }.
-output_instr(ann_hoisted(_), I, I) --> { error("output not implemented") }.
-output_instr(ann_live(_), I, I) --> { error("output not implemented") }.
-output_instr(ann_phi(_), I, I) --> { error("output not implemented") }.
-output_instr(ann_ref(_), I, I) --> { error("output not implemented") }.
-
 :- pred output_overflow(overflow::in, io__state::di,
 		io__state::uo) is det.
 output_overflow(OverFlow) -->
@@ -1275,19 +1258,6 @@
 
 :- pred output_methodref(methodref::in, ilasm_info::in, ilasm_info::out,
 		io__state::di, io__state::uo) is det.
-output_methodref(methodref(call_conv(IsInstance, _), ReturnType, 
-		StructuredName, ArgTypes), Info0, Info) -->
-	( { IsInstance = yes } ->
-		io__write_string("instance ")
-	;
-		[]
-	),
-	output_ret_type(ReturnType, Info0, Info1),
-	io__write_string(" "),
-	output_structured_name(StructuredName, Info1, Info2),
-	io__write_string("("),
-	ilasm__write_list(ArgTypes, ", ", output_type, Info2, Info),
-	io__write_string(")").
 output_methodref(methoddef(call_conv(IsInstance, _), ReturnType, 
 		ClassMemberName, ArgTypes), Info0, Info) -->
 	( { IsInstance = yes } ->
Index: compiler/ilds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ilds.m,v
retrieving revision 1.4
diff -u -r1.4 ilds.m
--- compiler/ilds.m	2001/05/02 16:34:36	1.4
+++ compiler/ilds.m	2001/05/27 14:31:15
@@ -23,6 +23,9 @@
 
 :- import_module list, std_util, bool, assoc_list.
 
+	% Returns the maximum stack usage of a list of IL instructions.
+:- func calculate_max_stack(list(ilds__instr)) = int.
+
 	% A method parameter
 :- type param == pair(
 			ilds__type,	% type of the parameter
@@ -42,8 +45,8 @@
 	---> methoddef(call_conv, ret_type, class_member_name,
 		list(ilds__type))
 			% XXX not sure whether methodref is used.
-	;    methodref(call_conv, ret_type, class_name,
-		list(ilds__type))
+%	;    methodref(call_conv, ret_type, class_name,
+%		list(ilds__type))
 	;    local_method(call_conv, ret_type, member_name,
 		list(ilds__type)).
 
@@ -51,6 +54,7 @@
 :- type fieldref
 	---> fieldref(ilds__type, class_member_name).
 
+
 % -------------------------------------------------------------------------
 
 	% if an assembly name is empty it is a reference to a local type
@@ -236,12 +240,10 @@
 	;	cpblk		% copy data from memory to memory
 	; 	div(signed)	% divide values
 	;	dup		% duplicate the value on the top of the stack
-	;	endcatch	% end exception handler
 	;	endfilter	% end filter clause of SEH exception handling
 	;	endfinally	% end finally clause of an exception block
 	;	initblk		% initialize a block
 	;	jmp(methodref) % jump to a specified method
-	;	jmpi		% exit current method and jump to spec method
 	;	ldarg(variable)	% load argument onto the stack
 	; 	ldarga(variable)	% fetch address of argument
 	;	ldc(simple_type, constant)	
@@ -279,8 +281,6 @@
 	;	callvirt(methodref)	% call a method associated with obj
 	;	castclass(ilds__type)	% cast obj to class
 	;	cpobj(ilds__type)	% copy a value type
-	;	entercrit		% enter a critical region with obj
-	;	exitcrit		% exit a critical region with obj
 	;	initobj(ilds__type)	% initialize a value type
 	;	isinst(ilds__type)	% test if obj is an instance
 	;	ldelem(simple_type)	% load an element of an array
@@ -289,9 +289,6 @@
 	;	ldflda(fieldref)	% load field address of obj
 	;	ldlen			% load length of array
 	;	ldobj(ilds__type)	% copy value type to stack
-	;	ldrefany(index)		% push refany in arg num onto stack
-		% XXX this appears to have been removed
-%	;	ldrefanya(index, ilds__type) % push refany addr into arg num
 	;	ldsfld(fieldref)	% load static field of a class
 	;	ldsflda(fieldref)	% load static field address
 	;	ldstr(string)		% load a literal string
@@ -300,29 +297,17 @@
 	;	mkrefany(ilds__type)	% push a refany pointer of type class
 	;	newarr(ilds__type)	% create a zero based 1D array
 	;	newobj(methodref)	% create new obj and call constructor
+	;	refanytype		% extract type info from refany nth arg
+	;	refanyval(ilds__type)	% extract type info from refany nth arg
+	;	rethrow			% rethrow an exception
+	;	sizeof(ilds__type)	% push the sizeof a value type
 	;	stelem(simple_type)	% store an element of an array
 	;	stfld(fieldref)		% store into a field of an object
+	;	stobj(ilds__type)
 	;	stsfld(fieldref)	% replace the value of field with val
 	;	throw			% throw an exception
-	;	typerefany(index)	% extract type info from refany nth arg
-	;	unbox(ilds__type)	% convert boxed value type to raw form
-
-	% ANNOTATIONS (only used for OPT-IL)
+	;	unbox(ilds__type).	% convert boxed value type to raw form
 
-	;	ann_call(signature)	% start of simple calling sequence
-	;	ann_catch		% start an exception filter or handler
-	;	ann_data(int)		% int32 bytes of uninterp. data follows 
-	;	ann_dead(location)	% stack location is no longer live
-	;	ann_def			% start SSA node
-	;	ann_hoisted(signature)  % start of complex argument evaluation
-	;	ann_hoisted_call	% start of simple part of hoisted call
-	;	ann_lab			% label (mark a branch target location)
-	;	ann_live(location)	% mark a stack location as live
-	;	ann_phi(list(node_number)) % merge SSA definition nodes
-	;	ann_ref(node_number).	% SSA reference node -- value at 
-					% node_number is same as next 
-					% instruction
-
 	% locations marked as dead by ann_dead -- positive numbers are
 	% stack slots, negative numbers are locals.
 :- type location == int.
@@ -353,6 +338,7 @@
 
 :- implementation.
 
+:- import_module int.
 :- import_module error_util.
 
 get_class_suffix(structured_name(_, FullName)) = SuffixName :-
@@ -380,7 +366,140 @@
 		structured_name(Assembly, NewClassName) :-
 	list__append(ClassName, ExtraClass, NewClassName).
 
+calculate_max_stack(Instrs) = 
+	calculate_max_stack_2(Instrs, 0, 0).
+
+:- func calculate_max_stack_2(list(ilds__instr), int, int) = int.
 
+calculate_max_stack_2([], _, Max) = Max.
+calculate_max_stack_2([I | Instrs], Current, Max) =  
+		calculate_max_stack_2(Instrs, NewCurrent, NewMax) :-
+	NewCurrent = Current + get_stack_difference(I),
+	NewMax = max(NewCurrent, Max).
+	
+:- func get_stack_difference(ilds__instr) = int.
+get_stack_difference(end_block(_, _)) 				= 0.
+get_stack_difference(comment(_)) 				= 0.
+get_stack_difference(start_block(_, _)) 			= 0.
+get_stack_difference(context(_, _)) 				= 0.
+get_stack_difference(label(_Label)) 				= 0. 
+
+get_stack_difference(add(_Overflow, _Signed))	 		= -1. 
+get_stack_difference((and)) 					= -1. 
+get_stack_difference(arglist) 					=  1.
+get_stack_difference(beq(_))					= -2.
+get_stack_difference(bge(_, _))					= -2.
+get_stack_difference(bgt(_, _))					= -2.
+get_stack_difference(ble(_, _))					= -2.
+get_stack_difference(blt(_, _))					= -2.
+get_stack_difference(bne(_, _))					= -2.
+get_stack_difference(br(_)) 					= 0.
+get_stack_difference(break) 					= 0.
+get_stack_difference(brtrue(_))					= -1.
+get_stack_difference(brfalse(_))				= -1.
+get_stack_difference(call(MethodRef)) = 
+	get_methodref_stack_difference(MethodRef).
+	% Remove an extra argument for the function pointer.
+get_stack_difference(calli(Signature)) = 
+	get_signature_stack_difference(Signature) - 1.
+get_stack_difference(callvirt(MethodRef)) = 
+	get_methodref_stack_difference(MethodRef).
+get_stack_difference(ceq) 					= -1. 
+get_stack_difference(cgt(_Signed)) 				= -1.
+get_stack_difference(ckfinite) 					= 0. 
+get_stack_difference(clt(_Signed)) 				= -1.
+get_stack_difference(conv(_SimpleType)) 			= 0. 
+get_stack_difference(cpblk) 					= -3. 
+get_stack_difference(div(_Signed)) 				= -1. 
+get_stack_difference(dup) 					= 1.
+get_stack_difference(endfilter) 				= -1. 
+get_stack_difference(endfinally) 				= -1. 
+get_stack_difference(initblk) 					= -3. 
+get_stack_difference(jmp(_MethodRef)) 				= 0. 
+get_stack_difference(ldarg(_)) 					= 1. 
+get_stack_difference(ldarga(_Variable)) 			= 1.
+get_stack_difference(ldc(_Type, _Const)) 			= 1.
+get_stack_difference(ldftn(_MethodRef)) 			= 1. 
+get_stack_difference(ldind(_SimpleType)) 			= 0. 
+get_stack_difference(ldloc(_Variable)) 				= 1. 
+get_stack_difference(ldloca(_Variable)) 			= 1.
+get_stack_difference(ldnull) 					= 1. 
+get_stack_difference(leave(_Target)) 				= 0. 
+get_stack_difference(localloc)		 			= 0. 
+get_stack_difference(mul(_Overflow, _Signed)) 			= -1. 
+get_stack_difference(neg) 					= 0. 
+get_stack_difference(nop) 					= 0. 
+get_stack_difference((not)) 					= 0. 
+get_stack_difference((or)) 					= -1. 
+get_stack_difference(pop) 					= -1. 
+get_stack_difference(rem(_Signed)) 				= -1. 
+get_stack_difference(ret) 					= 0. 
+get_stack_difference(shl) 					= -1. 
+get_stack_difference(shr(_Signed)) 				= -1. 
+get_stack_difference(starg(_Variable)) 				= -1.
+get_stack_difference(stind(_SimpleType)) 			= -2. 
+get_stack_difference(stloc(_Variable)) 				= -1. 
+get_stack_difference(sub(_OverFlow, _Signed)) 			= -1. 
+get_stack_difference(switch(_))					= -1.
+get_stack_difference(tailcall) 					= 0. 
+get_stack_difference(unaligned(_)) 				= 0.
+get_stack_difference(volatile) 					= 0. 
+get_stack_difference(xor) 					= -1. 
+
+get_stack_difference(box(_Type)) 				= 0. 
+get_stack_difference(castclass(_Type)) 				= 0.
+get_stack_difference(cpobj(_Type)) 				= -2. 
+get_stack_difference(initobj(_Type)) 				= -1. 
+get_stack_difference(isinst(_Type)) 				= 0. 
+get_stack_difference(ldelem(_SimpleType)) 			= -1. 
+get_stack_difference(ldelema(_Type)) 				= -1. 
+get_stack_difference(ldfld(_FieldRef)) 				= 0.
+get_stack_difference(ldflda(_FieldRef)) 			= 0.
+get_stack_difference(ldlen) 					= 0. 
+get_stack_difference(ldobj(_Type)) 				= 0.
+get_stack_difference(ldsfld(_FieldRef)) 			= 1. 
+get_stack_difference(ldsflda(_FieldRef)) 			= 1. 
+get_stack_difference(ldstr(_String)) 				= 1. 
+get_stack_difference(ldtoken(_)) 				= 1.
+get_stack_difference(ldvirtftn(_MethodRef)) 			= 0.
+get_stack_difference(mkrefany(_Type)) 				= 0.
+get_stack_difference(newarr(_Type)) 				= 0. 
+get_stack_difference(newobj(methoddef(_, _, _, Params))) =  Diff :-
+	Diff = -(length(Params)) + 1.
+get_stack_difference(newobj(local_method(_, _, _, Params))) =  Diff :-
+	Diff = -(length(Params)) + 1.
+get_stack_difference(refanytype)				= 0.
+get_stack_difference(refanyval(_Type)) 				= 0.
+get_stack_difference(rethrow)	 				= 0.
+get_stack_difference(sizeof(_Type))				= 1.
+get_stack_difference(stelem(_SimpleType)) 			= -3. 
+get_stack_difference(stfld(_FieldRef)) 				= -2. 
+get_stack_difference(stobj(_ClassName))				= -2.
+get_stack_difference(stsfld(_FieldRef)) 			= -1. 
+get_stack_difference(throw)					= -1.
+get_stack_difference(unbox(_Type)) 				= 0.
+
+
+	% Remove the params, and remove "this" if it is an instance
+	% method, but add the return type (if there is one).
+:- func get_methodref_stack_difference(methodref) = int.
+get_methodref_stack_difference(MethodRef) = Diff :-
+	( 
+		MethodRef = methoddef(CallConv, RetType, _, Params) 
+	; 
+		MethodRef = local_method(CallConv, RetType, _, Params)
+	),
+	InstanceDiff = ( CallConv = call_conv(yes, _) -> -1 ; 0 ),
+	RetDiff = ( RetType = void -> 0 ; 1),
+	Diff = -(length(Params)) + InstanceDiff + RetDiff.
+
+	% Remove the params, and remove "this" if it is an instance
+	% method, but add the return type (if there is one).
+:- func get_signature_stack_difference(signature) = int.
+get_signature_stack_difference(signature(CallConv, RetType, Params)) = Diff :-
+	InstanceDiff = ( CallConv = call_conv(yes, _) -> -1 ; 0 ),
+	RetDiff = ( RetType = void -> 0 ; 1),
+	Diff = -(length(Params)) + InstanceDiff + RetDiff.
 
 :- func this_file = string.
 this_file = "ilds.m".
Index: compiler/mlds_to_il.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_il.m,v
retrieving revision 1.28
diff -u -r1.28 mlds_to_il.m
--- compiler/mlds_to_il.m	2001/05/24 07:03:52	1.28
+++ compiler/mlds_to_il.m	2001/05/27 14:31:15
@@ -2700,10 +2700,7 @@
 make_method_defn(InstrTree) = MethodDecls :-
 	Instrs = list__condense(tree__flatten(InstrTree)),
 	MethodDecls = [
-			% XXX should avoid hard-coding "100" for
-			% the maximum static size -- not sure if we even
-			% need this anymore.
-		maxstack(int32(100)),
+		maxstack(int32(calculate_max_stack(Instrs))),
 			% note that we only need .zeroinit to ensure
 			% verifiability; for nonverifiable code,
 			% we could omit that (it ensures that all


-- 
       Tyson Dowd           # 
                            #  Surreal humour isn't everyone's cup of fur.
     trd at cs.mu.oz.au        # 
http://www.cs.mu.oz.au/~trd #
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list