1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
|
open Xi_lib
open Plugin_register
type plugin = string * (module Plugin.PLUGIN)
module Getters = struct
let make_live_variables_analysis (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_live_variables_analysis with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_dominators_analysis (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_dominators_analysis with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_reachability_analysis (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_reachability_analysis with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_scheduler (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_scheduler with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_natural_loops_analysis (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_natural_loops_analysis with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_spill_costs_analysis (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_spill_costs_analysis with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let lexer_and_parser (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.lexer_and_parser with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_typechecker (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_typechecker with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_translator (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_translator with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_jump_threading (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_jump_threading with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_constant_folding (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_constant_folding with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_hilower (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_hilower with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_callconv (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_callconv with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_mipslower (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_mipslower with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_register_allocator (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_register_allocator with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_register_coalescing (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_register_coalescing with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_dead_code_elimination (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_dead_code_elimination with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_codegen (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_codegen with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_constant_folding_analysis (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_constant_folding_analysis with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_interference_graph_analysis (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_interference_graph_analysis with
| Some x -> Some (name, Plugin.version, x)
| None -> None
let make_spilling (name, plugin) =
let module Plugin = (val plugin : Plugin.PLUGIN) in
match Plugin.make_spilling with
| Some x -> Some (name, Plugin.version, x)
| None -> None
end
module Resolver = struct
let rec find_module name getter = function
| [] ->
failwith @@ Format.sprintf "Cannot find %s" name
| x::xs ->
match getter x with
| Some (modname, version, impl) ->
Format.eprintf "module %s=%s:%s\n%!" name modname version;
impl
| None ->
find_module name getter xs
let make_live_variables_analysis = find_module "MakeLiveVariablesAnalysis" Getters.make_live_variables_analysis
let make_dominators_analysis = find_module "MakeDominanceAnalysis" Getters.make_dominators_analysis
let make_reachability_analysis = find_module "MakeReachabilityAnalysis" Getters.make_reachability_analysis
let make_scheduler = find_module "MakeScheduler" Getters.make_scheduler
let make_natural_loops_analysis = find_module "MakeNaturalLoopsAnalysis" Getters.make_natural_loops_analysis
let make_spill_costs_analysis = find_module "MakeSpillCostsAnalysis" Getters.make_spill_costs_analysis
let lexer_and_parser = find_module "LexerAndParser" Getters.lexer_and_parser
let make_typechecker = find_module "MakeTypechecker" Getters.make_typechecker
let make_translator = find_module "MakeTranslator" Getters.make_translator
let make_jump_threading = find_module "MakeJumpThreading" Getters.make_jump_threading
let make_constant_folding = find_module "MakeConstantFolding" Getters.make_constant_folding
let make_hilower = find_module "MakeHiLower" Getters.make_hilower
let make_callconv = find_module "MakeCallConv" Getters.make_callconv
let make_mipslower = find_module "MakeMipsLower" Getters.make_mipslower
let make_register_allocator = find_module "MakeRegisterAllocator" Getters.make_register_allocator
let make_register_coalescing = find_module "MakeRegisterCoalescing" Getters.make_register_coalescing
let make_dead_code_elimination = find_module "MakeDeadCodeElimination" Getters.make_dead_code_elimination
let make_codegen = find_module "MakeCodegen" Getters.make_codegen
let make_constant_folding_analysis = find_module "MakeConstantFoldingAnalysis" Getters.make_constant_folding_analysis
let make_interference_graph_analysis = find_module "MakeInterferenceGraphAnalysis" Getters.make_interference_graph_analysis
let make_spilling = find_module "MakeSpilling" Getters.make_spilling
end
let resolve_compiler_toolbox regdescr =
let module MakeLiveVariablesAnalysis = (val Resolver.make_live_variables_analysis !register) in
let module MakeDominatorsAnalysis = (val Resolver.make_dominators_analysis !register) in
let module MakeNaturalLoopsAnalysis = (val Resolver.make_natural_loops_analysis !register) in
let module MakeSpillCostsAnalysis = (val Resolver.make_spill_costs_analysis !register) in
let module MakeScheduler = (val Resolver.make_scheduler !register) in
let module MakeConstantFoldingAnalysis = (val Resolver.make_constant_folding_analysis !register) in
let module MakeInterferenceGraphAnalysis = (val Resolver.make_interference_graph_analysis !register) in
let module MakeSpilling = (val Resolver.make_spilling !register) in
let module MakeReachabilityAnalysis = (val Resolver.make_reachability_analysis !register) in
let module MakeRegisterCoalescing = (val Resolver.make_register_coalescing !register) in
let module M = struct
module LiveVariablesAnalysis = MakeLiveVariablesAnalysis()
module DominatorsAnalysis = MakeDominatorsAnalysis()
module Scheduler = MakeScheduler()
module NaturalLoopsAnalysis = MakeNaturalLoopsAnalysis()
module SpillCostsAnalysis = MakeSpillCostsAnalysis()
module RegistersDescription = (val regdescr : Ir_arch.REGISTERS_DESCRIPTION)
module ConstantFoldingAnalysis = MakeConstantFoldingAnalysis()
module InterferenceGraphAnalysis = MakeInterferenceGraphAnalysis()
module Spilling = MakeSpilling()
module ReachabilityAnalysis = MakeReachabilityAnalysis()
module RegisterCoalescing = MakeRegisterCoalescing()
end in
(module M : Iface.COMPILER_TOOLBOX)
let resolve_compiler_steps regdescr =
let module CompilerToolbox = (val resolve_compiler_toolbox regdescr : Iface.COMPILER_TOOLBOX) in
let module LexerAndParser = (val Resolver.lexer_and_parser !register) in
let module MakeTypechecker = (val Resolver.make_typechecker !register) in
let module MakeTranslator = (val Resolver.make_translator !register) in
let module MakeJumpThreading = (val Resolver.make_jump_threading !register) in
let module MakeConstantFolding = (val Resolver.make_constant_folding !register) in
let module MakeHiLower = (val Resolver.make_hilower !register) in
let module MakeCallConv = (val Resolver.make_callconv !register) in
let module MakeMipsLower = (val Resolver.make_mipslower !register) in
let module MakeRegisterAllocator = (val Resolver.make_register_allocator !register) in
let module MakeDeadCodeElimination = (val Resolver.make_dead_code_elimination !register) in
let module MakeCodegen = (val Resolver.make_codegen !register) in
let module Steps = struct
module Toolbox = CompilerToolbox
module LexerAndParser = LexerAndParser
module Typechecker = MakeTypechecker()
module Translator = MakeTranslator()
module JumpThreading = MakeJumpThreading()
module HiLower = MakeHiLower(CompilerToolbox)
module CallConv = MakeCallConv(CompilerToolbox)
module MipsLower = MakeMipsLower(CompilerToolbox)
module RegisterAllocator = MakeRegisterAllocator(CompilerToolbox)
module ConstantFolding = MakeConstantFolding(CompilerToolbox)
module DeadCodeElimination = MakeDeadCodeElimination(CompilerToolbox)
module Codegen = MakeCodegen(CompilerToolbox)
end in
(module Steps : Iface.COMPILER_STEPS)
let load_plugin path =
try
Plugin_register.current_file := Filename.basename path;
Dynlink.loadfile path;
Plugin_register.current_file := "";
with Dynlink.Error e ->
failwith @@ Format.sprintf "Cannot load plugin '%s': %s" path (Dynlink.error_message e)
|