Skip to content

Commit a58efbf

Browse files
committed
Merge pull request #1250 from dsyme/ilx-cleanup-6
Put union erasure in IlxGen phase
2 parents db7cea0 + 130fa52 commit a58efbf

File tree

22 files changed

+860
-1157
lines changed

22 files changed

+860
-1157
lines changed

src/absil/il.fs

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,46 +1124,7 @@ type ILInstr =
11241124
(* FOR EXTENSIONS, e.g. MS-ILX *)
11251125
| EI_ilzero of ILType
11261126
| EI_ldlen_multi of int32 * int32
1127-
| I_other of IlxExtensionInstr
11281127

1129-
and IlxExtensionInstr = Ext_instr of obj
1130-
1131-
1132-
// --------------------------------------------------------------------
1133-
// Helpers for the ILX extensions
1134-
// --------------------------------------------------------------------
1135-
1136-
type internal_instr_extension =
1137-
{ internalInstrExtDests: IlxExtensionInstr -> ILCodeLabel list;
1138-
internalInstrExtFallthrough: IlxExtensionInstr -> ILCodeLabel option;
1139-
internalInstrExtRelabel: (ILCodeLabel -> ILCodeLabel) -> IlxExtensionInstr -> IlxExtensionInstr; }
1140-
1141-
type ILInstrSetExtension<'T> =
1142-
{ instrExtDests: 'T -> ILCodeLabel list;
1143-
instrExtFallthrough: 'T -> ILCodeLabel option;
1144-
instrExtRelabel: (ILCodeLabel -> ILCodeLabel) -> 'T -> 'T; }
1145-
1146-
let instrExtensions = ref []
1147-
1148-
let RegisterInstructionSetExtension (ext: ILInstrSetExtension<'T>) =
1149-
if nonNil !instrExtensions then failwith "RegisterInstructionSetExtension: only one extension currently allowed";
1150-
let mk (x: 'T) = Ext_instr (box x)
1151-
let test (Ext_instr _x) = true
1152-
let dest (Ext_instr x) = (unbox x : 'T)
1153-
instrExtensions :=
1154-
{ internalInstrExtDests=(fun x -> ext.instrExtDests (dest x));
1155-
internalInstrExtFallthrough=(fun x -> ext.instrExtFallthrough (dest x));
1156-
internalInstrExtRelabel=(fun f x -> mk (ext.instrExtRelabel f (dest x))); }
1157-
:: !instrExtensions;
1158-
mk,test,dest
1159-
1160-
let rec find_extension s f l =
1161-
let rec look l1 =
1162-
match l1 with
1163-
| [] -> failwith ("extension for "+s+" not found")
1164-
| (h::t) -> match f h with None -> look t | Some res -> res
1165-
look l
1166-
11671128

11681129
type ILDebugMapping =
11691130
{ LocalIndex: int;
@@ -1180,7 +1141,6 @@ type ILBasicBlock =
11801141
member x.Fallthrough =
11811142
match x.LastInstruction with
11821143
| I_br l | I_brcmp (_,_,l) | I_switch (_,l) -> Some l
1183-
| I_other e -> find_extension "instr" (fun ext -> Some (ext.internalInstrExtFallthrough e)) !instrExtensions
11841144
| _ -> None
11851145

11861146

@@ -2065,7 +2025,6 @@ let destinationsOfInstr i =
20652025
| I_endfinally | I_endfilter | I_ret | I_throw | I_rethrow
20662026
| I_call (Tailcall,_,_)| I_callvirt (Tailcall,_,_)| I_callconstraint (Tailcall,_,_,_)
20672027
| I_calli (Tailcall,_,_) -> []
2068-
| I_other e -> find_extension "instr" (fun ext -> Some (ext.internalInstrExtDests e)) !instrExtensions
20692028
| _ -> []
20702029

20712030
let destinationsOfBasicBlock (bblock:ILBasicBlock) = destinationsOfInstr bblock.LastInstruction
@@ -2080,7 +2039,6 @@ let instrIsBasicBlockEnd i =
20802039
match i with
20812040
| I_leave _ | I_br _ | I_brcmp _ | I_switch _ | I_endfinally
20822041
| I_endfilter | I_ret | I_throw | I_rethrow -> true
2083-
| I_other e -> find_extension "instr" (fun ext -> Some (nonNil (ext.internalInstrExtDests e))) !instrExtensions
20842042
| _ -> false
20852043

20862044
let checks = false
@@ -3488,8 +3446,6 @@ type ILExceptionSpec =
34883446
{ exnRange: (ILCodeLabel * ILCodeLabel);
34893447
exnClauses: ILExceptionClause list }
34903448

3491-
type exceptions = ILExceptionSpec list
3492-
34933449
//-----------------------------------------------------------------------
34943450
// [instructions_to_code] makes the basic block structure of code from
34953451
// a primitive array of instructions. We
@@ -3586,7 +3542,6 @@ type BasicBlockStartsToCodeLabelsMap(instrs,tryspecs,localspecs,lab2pc) =
35863542
match i with
35873543
| I_leave l -> I_leave(c.lab2cl l)
35883544
| I_br l -> I_br (c.lab2cl l)
3589-
| I_other e -> I_other (find_extension "instr" (fun ext -> Some (ext.internalInstrExtRelabel c.lab2cl e)) !instrExtensions)
35903545
| I_brcmp (x,l1,l2) -> I_brcmp(x,c.lab2cl l1, c.lab2cl l2)
35913546
| I_switch (ls,l) -> I_switch(List.map c.lab2cl ls, c.lab2cl l)
35923547
| _ -> i
@@ -4881,7 +4836,7 @@ and refs_of_instr s x =
48814836
| I_ldarga _|I_ldarg _|I_leave _|I_br _
48824837
| I_brcmp _|I_rethrow|I_refanytype|I_ldlen|I_throw|I_initblk _ |I_cpblk _
48834838
| I_localloc|I_ret |I_endfilter|I_endfinally|I_arglist
4884-
| I_other _ | I_break
4839+
| I_break
48854840
| AI_add | AI_add_ovf | AI_add_ovf_un | AI_and | AI_div | AI_div_un | AI_ceq | AI_cgt | AI_cgt_un | AI_clt
48864841
| AI_clt_un | AI_conv _ | AI_conv_ovf _ | AI_conv_ovf_un _ | AI_mul | AI_mul_ovf | AI_mul_ovf_un | AI_rem | AI_rem_un
48874842
| AI_shl | AI_shr | AI_shr_un | AI_sub | AI_sub_ovf | AI_sub_ovf_un | AI_xor | AI_or | AI_neg | AI_not

src/absil/il.fsi

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,6 @@ type ILSourceMarker =
9898
member EndLine: int
9999
member EndColumn: int
100100

101-
/// Represents an extension to the algebra of instructions
102-
type IlxExtensionInstr
103-
104101
[<StructuralEquality; StructuralComparison>]
105102
type PublicKey =
106103
| PublicKey of byte[]
@@ -669,15 +666,6 @@ type ILInstr =
669666
// EXTENSIONS, e.g. MS-ILX
670667
| EI_ilzero of ILType
671668
| EI_ldlen_multi of int32 * int32
672-
| I_other of IlxExtensionInstr
673-
674-
// REVIEW: remove this open-ended way of extending the IL and just combine with ILX
675-
type ILInstrSetExtension<'Extension> =
676-
{ instrExtDests: ('Extension -> ILCodeLabel list);
677-
instrExtFallthrough: ('Extension -> ILCodeLabel option);
678-
instrExtRelabel: (ILCodeLabel -> ILCodeLabel) -> 'Extension -> 'Extension; }
679-
680-
val RegisterInstructionSetExtension: ILInstrSetExtension<'Extension> -> ('Extension -> IlxExtensionInstr) * (IlxExtensionInstr -> bool) * (IlxExtensionInstr -> 'Extension)
681669

682670
/// A list of instructions ending in an unconditionally
683671
/// branching instruction. A basic block has a label which must be unique

src/absil/ilmorph.fs

Lines changed: 0 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -65,90 +65,6 @@ let bblock_instr2instrs f bb =
6565

6666
{bb with Instructions = Array.sub codebuf 0 codebuf_size}
6767

68-
// Map each instruction in a basic block to a more complicated block that
69-
// may involve internal branching, but which will still have one entry
70-
// label and one exit label. This is used, for example, when macro-expanding
71-
// complicated high-level ILX instructions.
72-
// The morphing function is told the name of the input and output labels
73-
// that must be used for the generated block.
74-
// Optimize the case where an instruction gets mapped to a
75-
// straightline sequence of instructions by allowing the morphing
76-
// function to return a special result for this case.
77-
//
78-
// Let [i] be the instruction being morphed. If [i] is a control-flow
79-
// then instruction then [f] must return either a control-flow terminated
80-
// sequence of instructions or a block both of which must targets the same labels
81-
// (or a subset of the labels) targeted in [i]. If [i]
82-
// is not a if not a control-flow instruction then [f]
83-
// must return a block targeting the given output label.
84-
85-
let rec countAccInstrs (xss:ILInstr list list) acc =
86-
match xss with
87-
| [] -> acc
88-
| xs :: rest -> countAccInstrs rest (acc + List.length xs)
89-
90-
let rec commitAccInstrsAux (xs:ILInstr list) (arr:ILInstr[]) i =
91-
match xs with
92-
| [] -> ()
93-
| x :: rest -> arr.[i] <- x; commitAccInstrsAux rest arr (i+1)
94-
95-
// Fill in the array chunk by chunk from the end and work backwards
96-
let rec commitAccInstrs xss arr i =
97-
match xss with
98-
| [] -> assert (i = 0)
99-
| xs :: rest ->
100-
let n = List.length xs
101-
commitAccInstrsAux xs arr (i - n)
102-
commitAccInstrs rest arr (i - n)
103-
104-
// Write the accumulated instructions into an array. The fragments come in in reverse order.
105-
let commitAccBasicBlock (sofar: ILInstr list list) =
106-
let n = countAccInstrs sofar 0
107-
let arr = Array.zeroCreate n
108-
commitAccInstrs sofar arr n
109-
arr
110-
111-
[<Struct; NoComparison; NoEquality>]
112-
type InstrMorph(isInstrs:bool, instrs:ILInstr list, code: ILCode) =
113-
new (instrs:ILInstr list) = InstrMorph(true,instrs,Unchecked.defaultof<_>)
114-
new (code:ILCode) = InstrMorph(false,Unchecked.defaultof<_>,code)
115-
member x.IsInstrs = isInstrs
116-
member x.Instrs = instrs
117-
member x.Code = code
118-
119-
let rec bblockLoop f bb currBBlockInpLabel currInpLabel currOutLabel sofar instrs =
120-
match instrs with
121-
| (i::rest) ->
122-
let res : InstrMorph = f currInpLabel currOutLabel i
123-
if res.IsInstrs then
124-
// First possibility: return a list of instructions. No addresses get consumed.
125-
bblockLoop f bb currBBlockInpLabel currInpLabel currOutLabel (res.Instrs :: sofar) rest
126-
else
127-
let middle_bblock = res.Code
128-
let before_bblock =
129-
let instrs = commitAccBasicBlock ([I_br currInpLabel] :: sofar)
130-
mkBasicBlock {Label=currBBlockInpLabel;Instructions=instrs}
131-
if checking && uniqueEntryOfCode middle_bblock <> currInpLabel then
132-
dprintn ("*** warning when transforming bblock "^formatCodeLabel bb.Label^": bblock2code_instr2code: input label of returned block does not match the expected label while converting an instruction to a block.");
133-
let afterBlocks =
134-
match rest with
135-
| [] -> [] // the bblock has already been transformed
136-
| _ ->
137-
let newInLab = generateCodeLabel ()
138-
let newOutLab = generateCodeLabel ()
139-
[ bblockLoop f bb currOutLabel newInLab newOutLab [] rest ]
140-
141-
checkILCode
142-
(mkGroupBlock
143-
( currInpLabel :: (match rest with [] -> [] | _ -> [ currOutLabel ]),
144-
before_bblock :: middle_bblock :: afterBlocks))
145-
| [] ->
146-
let instrs = commitAccBasicBlock sofar
147-
mkBasicBlock {Label=currBBlockInpLabel;Instructions=instrs}
148-
149-
let bblock2code_instr2code (f:ILCodeLabel -> ILCodeLabel -> ILInstr -> InstrMorph) bb =
150-
bblockLoop f bb bb.Label (generateCodeLabel ()) (generateCodeLabel ()) [] (Array.toList bb.Instructions)
151-
15268
let rec block_bblock2code_typ2typ ((fbb,fty) as f) x =
15369
match x with
15470
| ILBasicBlock bblock -> fbb bblock
@@ -363,12 +279,6 @@ let fdefs_fdef2fdef f (m:ILFieldDefs) = mkILFields (List.map f m.AsList)
363279
(* use this when the conversion produces just one type... *)
364280
let morphILTypeDefs f (m: ILTypeDefs) = mkILTypeDefsFromArray (Array.map f m.AsArray)
365281

366-
let morphExpandILTypeDefs f (m:ILTypeDefs) =
367-
mkILTypeDefs (List.collect f m.AsList)
368-
369-
let morphILTypeDefsInILModule typesf m =
370-
{m with TypeDefs=typesf m.TypeDefs}
371-
372282
let locals_typ2typ f ls = ILList.map (local_typ2typ f) ls
373283
let freevars_typ2typ f ls = Array.map (freevar_typ2typ f) ls
374284

@@ -483,7 +393,6 @@ let morphILInstrsAndILTypesInILModule ilg (f1,f2) x =
483393
module_bblock2code_typ2typ ilg ((fun modCtxt tdefCtxt mdefCtxt i -> mkBasicBlock (bblock_instr2instr (f1 modCtxt tdefCtxt mdefCtxt) i)), f2) x
484394

485395
let morphILInstrsInILCode f x = topcode_bblock2code (fun i -> mkBasicBlock (bblock_instr2instrs f i)) x
486-
let morphExpandILInstrsInILCode f x = topcode_bblock2code (bblock2code_instr2code f) x
487396

488397
let morphILTypeInILModule ilg ftype y =
489398
let finstr modCtxt tdefCtxt mdefCtxt =

src/absil/ilmorph.fsi

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,18 @@
88
/// the ILMethodDef (if any) where the item occurs. etc.
99
module internal Microsoft.FSharp.Compiler.AbstractIL.Morphs
1010

11-
open Internal.Utilities
1211
open Microsoft.FSharp.Compiler.AbstractIL
13-
open Microsoft.FSharp.Compiler.AbstractIL.Internal
14-
open Microsoft.FSharp.Compiler.AbstractIL.Extensions.ILX.Types
1512
open Microsoft.FSharp.Compiler.AbstractIL.IL
1613

17-
type 'T morph = 'T -> 'T
18-
1914
/// Morph each scope reference inside a type signature.
20-
val morphILScopeRefsInILTypeRef: ILScopeRef morph -> ILTypeRef -> ILTypeRef
21-
22-
val morphILMethodDefs: ILMethodDef morph -> ILMethodDefs -> ILMethodDefs
23-
/// nb. does not do nested tdefs.
24-
val morphILTypeDefs: ILTypeDef morph -> ILTypeDefs -> ILTypeDefs
25-
26-
val morphExpandILTypeDefs: (ILTypeDef -> ILTypeDef list) -> ILTypeDefs -> ILTypeDefs
27-
28-
/// Morph all tables of ILTypeDefs in "ILModuleDef".
29-
val morphILTypeDefsInILModule: ILTypeDefs morph -> ILModuleDef -> ILModuleDef
15+
val morphILScopeRefsInILTypeRef: (ILScopeRef -> ILScopeRef) -> ILTypeRef -> ILTypeRef
3016

3117
/// Morph all type references throughout an entire module.
32-
val morphILTypeRefsInILModuleMemoized: ILGlobals -> ILTypeRef morph -> ILModuleDef -> ILModuleDef
18+
val morphILTypeRefsInILModuleMemoized: ILGlobals -> (ILTypeRef -> ILTypeRef) -> ILModuleDef -> ILModuleDef
3319

34-
val morphILScopeRefsInILModuleMemoized: ILGlobals -> ILScopeRef morph -> ILModuleDef -> ILModuleDef
20+
val morphILScopeRefsInILModuleMemoized: ILGlobals -> (ILScopeRef -> ILScopeRef) -> ILModuleDef -> ILModuleDef
3521

36-
val morphILMethodBody: ILMethodBody morph -> ILLazyMethodBody -> ILLazyMethodBody
3722
val morphILInstrsInILCode: (ILInstr -> ILInstr list) -> ILCode -> ILCode
3823

39-
[<Struct; NoComparison; NoEquality>]
40-
type InstrMorph =
41-
new : ILInstr list -> InstrMorph
42-
new : ILCode -> InstrMorph
43-
44-
val morphExpandILInstrsInILCode: (ILCodeLabel -> ILCodeLabel -> ILInstr -> InstrMorph) -> ILCode -> ILCode
45-
4624
val enablemorphCustomAttributeData : unit -> unit
4725
val disablemorphCustomAttributeData : unit -> unit

src/absil/ilprint.fs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -754,24 +754,7 @@ let rec goutput_instr env os inst =
754754
| I_cpobj tok -> output_string os "cpobj "; goutput_typ env os tok
755755
| I_sizeof tok -> output_string os "sizeof "; goutput_typ env os tok
756756
| I_seqpoint s -> output_source os s
757-
| (EI_ilzero ty) -> output_string os "ilzero "; goutput_typ env os ty
758-
| I_other e when isIlxExtInstr e ->
759-
match (destIlxExtInstr e) with
760-
| EI_castdata (check,ty,n) ->
761-
if not check then output_string os "/* unchecked. */ ";
762-
output_string os "castdata ";
763-
goutput_cuspec env os ty;
764-
output_string os ",";
765-
output_int os n
766-
| (EI_lddatatag (_,ty)) ->
767-
output_string os "lddatatag ";
768-
goutput_cuspec env os ty
769-
| (EI_datacase (_,ty,l,_)) ->
770-
output_string os "datacase";
771-
output_string os " ";
772-
goutput_cuspec env os ty;
773-
output_string os ",";
774-
output_parens (output_seq "," (fun os (x,y) -> output_int os x; output_string os ","; output_code_label os y)) os l
757+
| EI_ilzero ty -> output_string os "ilzero "; goutput_typ env os ty
775758
| _ ->
776759
output_string os "<printing for this instruction is not implemented>"
777760

src/absil/ilreflect.fs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1200,7 +1200,6 @@ let rec emitInstr cenv (modB : ModuleBuilder) emEnv (ilG:ILGenerator) instr =
12001200
| EI_ldlen_multi (_,m) ->
12011201
emitInstr cenv modB emEnv ilG (mkLdcInt32 m);
12021202
emitInstr cenv modB emEnv ilG (mkNormalCall(mkILNonGenericMethSpecInTy(cenv.ilg.typ_Array, ILCallingConv.Instance, "GetLength", [cenv.ilg.typ_int32], cenv.ilg.typ_int32)))
1203-
| I_other e when isIlxExtInstr e -> Printf.failwithf "the ILX instruction %s cannot be emitted" (e.ToString())
12041203
| i -> Printf.failwithf "the IL instruction %s cannot be emitted" (i.ToString())
12051204

12061205
//----------------------------------------------------------------------------

src/absil/ilx.fs

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -115,49 +115,14 @@ type IlxClosureSpec =
115115
mkILCtorMethSpecForTy (cloTy,fields |> Array.map (fun fv -> fv.fvType) |> Array.toList)
116116

117117

118-
type IlxInstr =
119-
// Discriminated unions
120-
| EI_castdata of bool * IlxUnionSpec * int
121-
| EI_datacase of avoidHelpers:bool * IlxUnionSpec * (int * ILCodeLabel) list * ILCodeLabel
122-
| EI_lddatatag of avoidHelpers:bool * IlxUnionSpec
123-
124-
125-
let destinations i =
126-
match i with
127-
| (EI_datacase (_,_,ls,l)) ->
128-
let hashSet = System.Collections.Generic.HashSet<_>(HashIdentity.Structural)
129-
[yield l
130-
for (_,l) in ls do
131-
if hashSet.Add l then
132-
yield l]
133-
| _ -> []
134-
135-
let fallthrough i =
136-
match i with
137-
| (EI_datacase (_,_,_,l)) -> Some l
138-
| _ -> None
139-
140-
let remapIlxLabels lab2cl i =
141-
match i with
142-
| EI_datacase (z,x,ls,l) -> EI_datacase (z,x,List.map (fun (y,l) -> (y,lab2cl l)) ls, lab2cl l)
143-
| _ -> i
144-
145-
let (mkIlxExtInstr,isIlxExtInstr,destIlxExtInstr) =
146-
RegisterInstructionSetExtension
147-
{ instrExtDests=destinations
148-
instrExtFallthrough=fallthrough
149-
instrExtRelabel=remapIlxLabels }
150-
151-
let mkIlxInstr i = I_other (mkIlxExtInstr i)
152-
153118
// Define an extension of the IL algebra of type definitions
154119
type IlxClosureInfo =
155120
{ cloStructure: IlxClosureLambdas;
156121
cloFreeVars: IlxClosureFreeVar[];
157122
cloCode: Lazy<ILMethodBody>;
158123
cloSource: ILSourceMarker option}
159124

160-
and IlxUnionInfo =
125+
type IlxUnionInfo =
161126
{ /// is the representation public?
162127
cudReprAccess: ILMemberAccess;
163128
/// are the representation public?

src/absil/ilx.fsi

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -89,18 +89,6 @@ type IlxClosureApps =
8989
| Apps_app of ILType * IlxClosureApps
9090
| Apps_done of ILType
9191

92-
/// ILX extensions to the instruction set.
93-
type IlxInstr =
94-
| EI_castdata of bool * IlxUnionSpec * int
95-
| EI_datacase of avoidHelpers:bool * IlxUnionSpec * (int * ILCodeLabel) list * ILCodeLabel
96-
| EI_lddatatag of avoidHelpers:bool * IlxUnionSpec
97-
98-
val mkIlxExtInstr: (IlxInstr -> IlxExtensionInstr)
99-
val isIlxExtInstr: (IlxExtensionInstr -> bool)
100-
val destIlxExtInstr: (IlxExtensionInstr -> IlxInstr)
101-
102-
val mkIlxInstr: IlxInstr -> ILInstr
103-
10492
// --------------------------------------------------------------------
10593
// ILX extensions to the kinds of type definitions available
10694
// --------------------------------------------------------------------
@@ -111,7 +99,7 @@ type IlxClosureInfo =
11199
cloCode: Lazy<ILMethodBody>;
112100
cloSource: ILSourceMarker option}
113101

114-
and IlxUnionInfo =
102+
type IlxUnionInfo =
115103
{ /// Is the representation public?
116104
cudReprAccess: ILMemberAccess;
117105
/// Are the representation helpers public?

0 commit comments

Comments
 (0)