rltk 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +46 -2
- data/Rakefile +10 -1
- data/lib/rltk/ast.rb +48 -3
- data/lib/rltk/cfg.rb +90 -21
- data/lib/rltk/cg/bindings.rb +37 -5
- data/lib/rltk/cg/execution_engine.rb +11 -12
- data/lib/rltk/cg/generated_bindings.rb +2 -8
- data/lib/rltk/cg/generated_extended_bindings.rb +244 -0
- data/lib/rltk/cg/llvm.rb +64 -6
- data/lib/rltk/cg/module.rb +80 -2
- data/lib/rltk/cg/pass_manager.rb +28 -15
- data/lib/rltk/cg/support.rb +2 -0
- data/lib/rltk/cg/target.rb +100 -0
- data/lib/rltk/cg/triple.rb +58 -0
- data/lib/rltk/cg/type.rb +7 -7
- data/lib/rltk/cg/value.rb +25 -1
- data/lib/rltk/cg.rb +1 -1
- data/lib/rltk/parser.rb +91 -43
- data/lib/rltk/util/monkeys.rb +8 -4
- data/lib/rltk/version.rb +1 -1
- data/test/tc_ast.rb +62 -8
- data/test/tc_parser.rb +137 -0
- metadata +4 -2
@@ -32,6 +32,52 @@ module RLTK::CG::Bindings
|
|
32
32
|
# @scope class
|
33
33
|
attach_function :target_version, :LLVMTargetVersion, [], :string
|
34
34
|
|
35
|
+
# (Not documented)
|
36
|
+
#
|
37
|
+
# @method initialize_all_asm_parsers()
|
38
|
+
# @return [nil]
|
39
|
+
# @scope class
|
40
|
+
attach_function :initialize_all_asm_parsers, :LLVMInitializeAllAsmParsers, [], :void
|
41
|
+
|
42
|
+
# (Not documented)
|
43
|
+
#
|
44
|
+
# @method initialize_all_asm_printers()
|
45
|
+
# @return [nil]
|
46
|
+
# @scope class
|
47
|
+
attach_function :initialize_all_asm_printers, :LLVMInitializeAllAsmPrinters, [], :void
|
48
|
+
|
49
|
+
# (Not documented)
|
50
|
+
#
|
51
|
+
# @method initialize_native_target_asm_parser()
|
52
|
+
# @return [nil]
|
53
|
+
# @scope class
|
54
|
+
attach_function :initialize_native_target_asm_parser, :LLVMInitializeNativeTargetAsmParser, [], :void
|
55
|
+
|
56
|
+
# (Not documented)
|
57
|
+
#
|
58
|
+
# @method initialize_native_target_asm_printer()
|
59
|
+
# @return [nil]
|
60
|
+
# @scope class
|
61
|
+
attach_function :initialize_native_target_asm_printer, :LLVMInitializeNativeTargetAsmPrinter, [], :void
|
62
|
+
|
63
|
+
# (Not documented)
|
64
|
+
#
|
65
|
+
# @method load_module_from_ir_file(file_name, context)
|
66
|
+
# @param [String] file_name
|
67
|
+
# @param [FFI::Pointer(ContextRef)] context
|
68
|
+
# @return [FFI::Pointer(ModuleRef)]
|
69
|
+
# @scope class
|
70
|
+
attach_function :load_module_from_ir_file, :LLVMLoadModuleFromIRFile, [:string, :pointer], :pointer
|
71
|
+
|
72
|
+
# (Not documented)
|
73
|
+
#
|
74
|
+
# @method print_module(mod, fd)
|
75
|
+
# @param [FFI::Pointer(ModuleRef)] mod
|
76
|
+
# @param [Integer] fd
|
77
|
+
# @return [nil]
|
78
|
+
# @scope class
|
79
|
+
attach_function :print_module, :LLVMPrintModule, [:pointer, :int], :void
|
80
|
+
|
35
81
|
# (Not documented)
|
36
82
|
#
|
37
83
|
# @method load_library_permanently(filename)
|
@@ -40,4 +86,202 @@ module RLTK::CG::Bindings
|
|
40
86
|
# @scope class
|
41
87
|
attach_function :load_library_permanently, :LLVMLoadLibraryPermanently, [:string], :int
|
42
88
|
|
89
|
+
# (Not documented)
|
90
|
+
#
|
91
|
+
# @method print_value(val, fd)
|
92
|
+
# @param [FFI::Pointer(ValueRef)] val
|
93
|
+
# @param [Integer] fd
|
94
|
+
# @return [nil]
|
95
|
+
# @scope class
|
96
|
+
attach_function :print_value, :LLVMPrintValue, [:pointer, :int], :void
|
97
|
+
|
98
|
+
# (Not documented)
|
99
|
+
#
|
100
|
+
# <em>This entry is only for documentation and no real method. The FFI::Enum can be accessed via #enum_type(:code_model).</em>
|
101
|
+
#
|
102
|
+
# === Options:
|
103
|
+
# :default_cmodel ::
|
104
|
+
#
|
105
|
+
# :kernel ::
|
106
|
+
#
|
107
|
+
# :small ::
|
108
|
+
#
|
109
|
+
# :medium ::
|
110
|
+
#
|
111
|
+
# :large ::
|
112
|
+
#
|
113
|
+
#
|
114
|
+
# @method _enum_code_model_
|
115
|
+
# @return [Symbol]
|
116
|
+
# @scope class
|
117
|
+
enum :code_model, [
|
118
|
+
:default_cmodel, 0,
|
119
|
+
:kernel, 1,
|
120
|
+
:small, 2,
|
121
|
+
:medium, 3,
|
122
|
+
:large, 4
|
123
|
+
]
|
124
|
+
|
125
|
+
# (Not documented)
|
126
|
+
#
|
127
|
+
# <em>This entry is only for documentation and no real method. The FFI::Enum can be accessed via #enum_type(:reloc_model).</em>
|
128
|
+
#
|
129
|
+
# === Options:
|
130
|
+
# :default_rmodel ::
|
131
|
+
#
|
132
|
+
# :static ::
|
133
|
+
#
|
134
|
+
# :pic ::
|
135
|
+
#
|
136
|
+
# :dynamic_no_pic ::
|
137
|
+
#
|
138
|
+
#
|
139
|
+
# @method _enum_reloc_model_
|
140
|
+
# @return [Symbol]
|
141
|
+
# @scope class
|
142
|
+
enum :reloc_model, [
|
143
|
+
:default_rmodel, 0,
|
144
|
+
:static, 1,
|
145
|
+
:pic, 2,
|
146
|
+
:dynamic_no_pic, 3
|
147
|
+
]
|
148
|
+
|
149
|
+
# (Not documented)
|
150
|
+
#
|
151
|
+
# <em>This entry is only for documentation and no real method. The FFI::Enum can be accessed via #enum_type(:compile_type).</em>
|
152
|
+
#
|
153
|
+
# === Options:
|
154
|
+
# :asm ::
|
155
|
+
#
|
156
|
+
# :object ::
|
157
|
+
#
|
158
|
+
#
|
159
|
+
# @method _enum_compile_type_
|
160
|
+
# @return [Symbol]
|
161
|
+
# @scope class
|
162
|
+
enum :compile_type, [
|
163
|
+
:asm, 0,
|
164
|
+
:object, 1
|
165
|
+
]
|
166
|
+
|
167
|
+
# (Not documented)
|
168
|
+
class OpaqueTarget < FFI::Struct
|
169
|
+
layout :dummy, :char
|
170
|
+
end
|
171
|
+
|
172
|
+
# (Not documented)
|
173
|
+
class OpaqueTargetMachine < FFI::Struct
|
174
|
+
layout :dummy, :char
|
175
|
+
end
|
176
|
+
|
177
|
+
# (Not documented)
|
178
|
+
class OpaqueTriple < FFI::Struct
|
179
|
+
layout :dummy, :char
|
180
|
+
end
|
181
|
+
|
182
|
+
# // Utility
|
183
|
+
#
|
184
|
+
# @method build_features_string(attrs, num_attrs)
|
185
|
+
# @param [FFI::Pointer(**CharS)] attrs
|
186
|
+
# @param [Integer] num_attrs
|
187
|
+
# @return [String]
|
188
|
+
# @scope class
|
189
|
+
attach_function :build_features_string, :LLVMBuildFeaturesString, [:pointer, :int], :string
|
190
|
+
|
191
|
+
# (Not documented)
|
192
|
+
#
|
193
|
+
# @method compile_module_to_file(mod, machine, pm, file_name, ctype, opt_level, no_verify)
|
194
|
+
# @param [FFI::Pointer(ModuleRef)] mod
|
195
|
+
# @param [OpaqueTargetMachine] machine
|
196
|
+
# @param [FFI::Pointer(PassManagerRef)] pm
|
197
|
+
# @param [String] file_name
|
198
|
+
# @param [Symbol from _enum_compile_type_] ctype
|
199
|
+
# @param [Integer] opt_level
|
200
|
+
# @param [Integer] no_verify
|
201
|
+
# @return [nil]
|
202
|
+
# @scope class
|
203
|
+
attach_function :compile_module_to_file, :LLVMCompileModuleToFile, [:pointer, OpaqueTargetMachine, :pointer, :string, :compile_type, :uint, :uint], :void
|
204
|
+
|
205
|
+
# (Not documented)
|
206
|
+
#
|
207
|
+
# @method ecb_initialize_all_targets()
|
208
|
+
# @return [nil]
|
209
|
+
# @scope class
|
210
|
+
attach_function :ecb_initialize_all_targets, :LLVMECBInitializeAllTargets, [], :void
|
211
|
+
|
212
|
+
# (Not documented)
|
213
|
+
#
|
214
|
+
# @method ecb_initialize_native_target()
|
215
|
+
# @return [nil]
|
216
|
+
# @scope class
|
217
|
+
attach_function :ecb_initialize_native_target, :LLVMECBInitializeNativeTarget, [], :void
|
218
|
+
|
219
|
+
# // Target
|
220
|
+
#
|
221
|
+
# @method get_target_from_name(name)
|
222
|
+
# @param [String] name
|
223
|
+
# @return [OpaqueTarget]
|
224
|
+
# @scope class
|
225
|
+
attach_function :get_target_from_name, :LLVMGetTargetFromName, [:string], OpaqueTarget
|
226
|
+
|
227
|
+
# (Not documented)
|
228
|
+
#
|
229
|
+
# @method get_target_from_triple(triple)
|
230
|
+
# @param [OpaqueTriple] triple
|
231
|
+
# @return [OpaqueTarget]
|
232
|
+
# @scope class
|
233
|
+
attach_function :get_target_from_triple, :LLVMGetTargetFromTriple, [OpaqueTriple], OpaqueTarget
|
234
|
+
|
235
|
+
# // Target Machine
|
236
|
+
#
|
237
|
+
# @method create_target_machine(target, triple, mcpu, features, rmodel, cmodel)
|
238
|
+
# @param [OpaqueTarget] target
|
239
|
+
# @param [String] triple
|
240
|
+
# @param [String] mcpu
|
241
|
+
# @param [String] features
|
242
|
+
# @param [Symbol from _enum_reloc_model_] rmodel
|
243
|
+
# @param [Symbol from _enum_code_model_] cmodel
|
244
|
+
# @return [OpaqueTargetMachine]
|
245
|
+
# @scope class
|
246
|
+
attach_function :create_target_machine, :LLVMCreateTargetMachine, [OpaqueTarget, :string, :string, :string, :reloc_model, :code_model], OpaqueTargetMachine
|
247
|
+
|
248
|
+
# (Not documented)
|
249
|
+
#
|
250
|
+
# @method set_target_machine_asm_verbosity(machine, boolean)
|
251
|
+
# @param [OpaqueTargetMachine] machine
|
252
|
+
# @param [Integer] boolean
|
253
|
+
# @return [nil]
|
254
|
+
# @scope class
|
255
|
+
attach_function :set_target_machine_asm_verbosity, :LLVMSetTargetMachineASMVerbosity, [OpaqueTargetMachine, :int], :void
|
256
|
+
|
257
|
+
# // Triple
|
258
|
+
#
|
259
|
+
# @method get_host_triple()
|
260
|
+
# @return [OpaqueTriple]
|
261
|
+
# @scope class
|
262
|
+
attach_function :get_host_triple, :LLVMGetHostTriple, [], OpaqueTriple
|
263
|
+
|
264
|
+
# (Not documented)
|
265
|
+
#
|
266
|
+
# @method get_host_triple_string()
|
267
|
+
# @return [String]
|
268
|
+
# @scope class
|
269
|
+
attach_function :get_host_triple_string, :LLVMGetHostTripleString, [], :string
|
270
|
+
|
271
|
+
# (Not documented)
|
272
|
+
#
|
273
|
+
# @method get_triple_string(triple)
|
274
|
+
# @param [OpaqueTriple] triple
|
275
|
+
# @return [String]
|
276
|
+
# @scope class
|
277
|
+
attach_function :get_triple_string, :LLVMGetTripleString, [OpaqueTriple], :string
|
278
|
+
|
279
|
+
# (Not documented)
|
280
|
+
#
|
281
|
+
# @method triple_create(string)
|
282
|
+
# @param [String] string
|
283
|
+
# @return [OpaqueTriple]
|
284
|
+
# @scope class
|
285
|
+
attach_function :triple_create, :LLVMTripleCreate, [:string], OpaqueTriple
|
286
|
+
|
43
287
|
end
|
data/lib/rltk/cg/llvm.rb
CHANGED
@@ -19,27 +19,85 @@ module RLTK::CG # :nodoc:
|
|
19
19
|
|
20
20
|
# This module contains global operations on the LLVM compiler infrastructure.
|
21
21
|
module LLVM
|
22
|
-
# Initialize LLVM to generate code for a given architecture.
|
22
|
+
# Initialize LLVM to generate code for a given architecture. You may
|
23
|
+
# also specify :all to initialize all targets or :native to
|
24
|
+
# initialize the host target.
|
23
25
|
#
|
24
26
|
# @see Bindings::ARCHS
|
25
27
|
#
|
26
28
|
# @param [Symbol] arch Architecture to initialize LLVM for.
|
27
29
|
#
|
28
|
-
# @raise [
|
30
|
+
# @raise [ArgumentError] An error is raised if an unsupported architecture is specified.
|
29
31
|
#
|
30
|
-
# @return [
|
32
|
+
# @return [void]
|
31
33
|
def self.init(arch)
|
32
|
-
if
|
34
|
+
if arch == :all
|
35
|
+
Bindings.ecb_initialize_all_targets
|
36
|
+
|
37
|
+
elsif arch == :native
|
38
|
+
Bindings.ecb_initialize_native_target
|
39
|
+
|
40
|
+
elsif Bindings::ARCHS.include?(arch) or Bindings::ARCHS.map { |sym| sym.to_s.downcase.to_sym }.include?(arch)
|
33
41
|
arch = Bindings.get_bname(arch)
|
34
42
|
|
35
43
|
Bindings.send("initialize_#{arch}_target".to_sym)
|
36
44
|
Bindings.send("initialize_#{arch}_target_info".to_sym)
|
37
45
|
Bindings.send("initialize_#{arch}_target_mc".to_sym)
|
38
46
|
|
39
|
-
|
47
|
+
else
|
48
|
+
raise ArgumentError, "Unsupported architecture specified: #{arch}."
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Initialize a given ASM parser inside LLVM. You may also specify
|
53
|
+
# :all to initialize all ASM parsers.
|
54
|
+
#
|
55
|
+
# @see Bindings::ASM_PARSERS
|
56
|
+
#
|
57
|
+
# @param [Symbol] asm Assembly language type to initialize parser for.
|
58
|
+
#
|
59
|
+
# @raise [ArgumentError] An error is raised if an unsupported assembler parser is specified.
|
60
|
+
#
|
61
|
+
# @return [void]
|
62
|
+
def self.init_asm_parser(asm)
|
63
|
+
if asm == :all
|
64
|
+
Bindings.initialize_all_asm_parsers
|
65
|
+
|
66
|
+
elsif Bindings::ASM_PARSERS.include?(asm) or Bindings::ASM_PARSERS.map { |sym| sym.to_s.downcase.to_sym }.include?(asm)
|
67
|
+
asm = Bindings.get_bname(asm)
|
68
|
+
|
69
|
+
Bindings.send("initialize_#{asm}_asm_parser".to_sym)
|
70
|
+
|
71
|
+
else
|
72
|
+
raise ArgumentError, "Unsupported assembler type specified: #{asm}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Initialize a given ASM printer inside LLVM. You may also specify
|
77
|
+
# :all to initialize all ASM printers or :native to initialize the
|
78
|
+
# printer for the host machine's assembly language.
|
79
|
+
#
|
80
|
+
# @see Bindings::ASM_PRINTERS
|
81
|
+
#
|
82
|
+
# @param [Symbol] asm Assembly language type to initialize printer for.
|
83
|
+
#
|
84
|
+
# @raise [ArgumentError] An error is raised if an unsupported assembler printer is specified.
|
85
|
+
#
|
86
|
+
# @return [void]
|
87
|
+
def self.init_asm_printer(asm)
|
88
|
+
if asm == :all
|
89
|
+
Bindings.initialize_all_asm_printers
|
90
|
+
|
91
|
+
elsif asm == :native
|
92
|
+
Bindings.initialize_native_asm_printer
|
93
|
+
|
94
|
+
elsif Bindings::ASM_PRINTERS.include?(asm) or Bindings::ASM_PRINTERS.map { |sym| sym.to_s.downcase.to_sym }.include?(asm)
|
95
|
+
asm = Bindings.get_bname(asm)
|
96
|
+
|
97
|
+
Bindings.send("initialize_#{asm}_asm_printer".to_sym)
|
40
98
|
|
41
99
|
else
|
42
|
-
raise "Unsupported
|
100
|
+
raise ArgumentError, "Unsupported assembler type specified: #{asm}"
|
43
101
|
end
|
44
102
|
end
|
45
103
|
|
data/lib/rltk/cg/module.rb
CHANGED
@@ -22,11 +22,15 @@ module RLTK::CG # :nodoc:
|
|
22
22
|
class Module
|
23
23
|
include BindingClass
|
24
24
|
|
25
|
+
# @!attribute [rw] engine
|
26
|
+
# @return [ExecutionEngine, nil] Execution engine associated with this module.
|
27
|
+
attr_accessor :engine
|
28
|
+
|
25
29
|
# Load a module from LLVM bitcode.
|
26
30
|
#
|
27
31
|
# @see MemoryBuffer#initialize
|
28
32
|
#
|
29
|
-
# @param [MemoryBuffer, FFI::Pointer, String, nil] overloaded Where to read the
|
33
|
+
# @param [MemoryBuffer, FFI::Pointer, String, nil] overloaded Where to read the bitecode from.
|
30
34
|
#
|
31
35
|
# @return [Module]
|
32
36
|
def self.read_bitcode(overloaded)
|
@@ -44,6 +48,15 @@ module RLTK::CG # :nodoc:
|
|
44
48
|
end
|
45
49
|
end
|
46
50
|
|
51
|
+
# Load a Module form an LLVM IR file.
|
52
|
+
#
|
53
|
+
# @param [String] file_name Name of file containing LLVM IR module.
|
54
|
+
#
|
55
|
+
# @return [Module]
|
56
|
+
def self.read_ir_file(file_name, context = Context.global)
|
57
|
+
self.new(Bindings.load_module_from_ir_file(file_name, context))
|
58
|
+
end
|
59
|
+
|
47
60
|
# Create a new LLVM module.
|
48
61
|
#
|
49
62
|
# @param [FFI::Pointer, String] overloaded Pointer to existing module or name of new module.
|
@@ -66,6 +79,19 @@ module RLTK::CG # :nodoc:
|
|
66
79
|
self.instance_exec(&block) if block
|
67
80
|
end
|
68
81
|
|
82
|
+
# Compile this module to an assembly or object file.
|
83
|
+
#
|
84
|
+
# @param [String] file_name Name of output file.
|
85
|
+
# @param [:asm, :object] mode Generate assembly or object file?
|
86
|
+
# @param [TargetMachine] machine Machine type to target.
|
87
|
+
# @param [0, 1, 2, 3] opt_level Optimization level to use during compilation.
|
88
|
+
# @param [Boolean] verify Verify the module before compilation or not.
|
89
|
+
#
|
90
|
+
# @return [void]
|
91
|
+
def compile(file_name, mode = :object, machine = TargetMachine.host, opt_level = 2, verify = true)
|
92
|
+
Bindings.compile_module_to_file(@ptr, machine, self.pm, file_name, mode, opt_level, (!verify).to_i)
|
93
|
+
end
|
94
|
+
|
69
95
|
# @return [Context] Context in which this module exists.
|
70
96
|
def context
|
71
97
|
Context.new(Bindings.get_module_context(@ptr))
|
@@ -82,13 +108,49 @@ module RLTK::CG # :nodoc:
|
|
82
108
|
end
|
83
109
|
end
|
84
110
|
|
85
|
-
# Print the IR of this
|
111
|
+
# Print the LLVM IR representation of this value to standard error.
|
112
|
+
# This function is the debugging version of the more general purpose
|
113
|
+
# {#print} method.
|
114
|
+
#
|
115
|
+
# @see #print
|
86
116
|
#
|
87
117
|
# @return [void]
|
88
118
|
def dump
|
89
119
|
Bindings.dump_module(@ptr)
|
90
120
|
end
|
91
121
|
|
122
|
+
# @return [FunctionPassManager] Function pass manager for this module.
|
123
|
+
def function_pass_manager
|
124
|
+
@function_pass_manager ||= FunctionPassManager.new(self)
|
125
|
+
end
|
126
|
+
alias :fpm :function_pass_manager
|
127
|
+
|
128
|
+
# @return [PassManager] Pass manager for this module.
|
129
|
+
def pass_manager
|
130
|
+
@pass_manager ||= PassManager.new(self)
|
131
|
+
end
|
132
|
+
alias :pm :pass_manager
|
133
|
+
|
134
|
+
# Print the LLVM IR representation of this module to a file. The
|
135
|
+
# file may be specified via a file name (which will be created or
|
136
|
+
# truncated) or an object that responds to #fileno.
|
137
|
+
#
|
138
|
+
# @LLVMECB
|
139
|
+
#
|
140
|
+
# @param [String, #fileno] io File name or object with a file descriptor to print to.
|
141
|
+
#
|
142
|
+
# @return [void]
|
143
|
+
def print(io = $stdout)
|
144
|
+
case io
|
145
|
+
when String
|
146
|
+
File.open(io, 'w') do |f|
|
147
|
+
Bindings.print_module(@ptr, f.fileno)
|
148
|
+
end
|
149
|
+
else
|
150
|
+
Bindings.print_module(@ptr, io.fileno)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
92
154
|
# @return [FunctionCollection] Proxy object for inspecting this module's functions.
|
93
155
|
def functions
|
94
156
|
@functions ||= FunctionCollection.new(self)
|
@@ -100,6 +162,22 @@ module RLTK::CG # :nodoc:
|
|
100
162
|
@globals ||= GlobalCollection.new(self)
|
101
163
|
end
|
102
164
|
|
165
|
+
# Set the module's target triple.
|
166
|
+
#
|
167
|
+
# @param [String] triple Triple value to set.
|
168
|
+
#
|
169
|
+
# @return [void]
|
170
|
+
def target=(triple)
|
171
|
+
Bindings.set_target(@ptr, triple)
|
172
|
+
end
|
173
|
+
|
174
|
+
# Get the module's target triple.
|
175
|
+
#
|
176
|
+
# @return [String]
|
177
|
+
def target
|
178
|
+
Bindings.get_target(@ptr)
|
179
|
+
end
|
180
|
+
|
103
181
|
# Write the module as LLVM bitcode to a file.
|
104
182
|
#
|
105
183
|
# @param [#path, #fileno, Integer, String] overloaded Where to write the bitcode.
|
data/lib/rltk/cg/pass_manager.rb
CHANGED
@@ -68,18 +68,20 @@ module RLTK::CG # :nodoc:
|
|
68
68
|
:Verifier => :verifier
|
69
69
|
}
|
70
70
|
|
71
|
-
#
|
72
|
-
# {
|
73
|
-
#
|
71
|
+
# Create a new pass manager. You should never have to do this as
|
72
|
+
# {Module Modules} should create PassManagers for you whenever they
|
73
|
+
# are requested.
|
74
74
|
#
|
75
|
-
# @
|
76
|
-
#
|
77
|
-
|
75
|
+
# @see Module#pass_manager
|
76
|
+
#
|
77
|
+
# @param [Module] mod Module this pass manager belongs to.
|
78
|
+
def initialize(mod)
|
78
79
|
# LLVM Initialization
|
79
80
|
@ptr = Bindings.create_pass_manager
|
80
81
|
@mod = mod
|
81
82
|
|
82
|
-
|
83
|
+
# Set the target data if the module is associated with a execution engine.
|
84
|
+
self.target_data = mod.engine.target_data if mod.engine
|
83
85
|
|
84
86
|
# RLTK Initialization
|
85
87
|
@enabled = Array.new
|
@@ -152,6 +154,15 @@ module RLTK::CG # :nodoc:
|
|
152
154
|
Bindings.run_pass_manager(@ptr, @mod).to_bool
|
153
155
|
end
|
154
156
|
|
157
|
+
# Set the target data for this pass manager.
|
158
|
+
#
|
159
|
+
# @param [TargetData] data
|
160
|
+
#
|
161
|
+
# @return [void]
|
162
|
+
def target_data=(data)
|
163
|
+
Bindings.add_target_data(check_type(data, TargetData, 'data'), @ptr)
|
164
|
+
end
|
165
|
+
|
155
166
|
protected
|
156
167
|
# Empty method used by {FunctionPassManager} to clean up resources.
|
157
168
|
def finalize
|
@@ -161,19 +172,21 @@ module RLTK::CG # :nodoc:
|
|
161
172
|
# A FunctionPassManager is responsible for scheduling and running optimization
|
162
173
|
# passes on individual functions inside the context of a module.
|
163
174
|
class FunctionPassManager < PassManager
|
164
|
-
#
|
165
|
-
# this as {
|
166
|
-
#
|
175
|
+
# Create a new function pass manager. You should never have to do
|
176
|
+
# this as {Module Modules} should create FunctionPassManagers for you
|
177
|
+
# whenever they are requested.
|
178
|
+
#
|
179
|
+
# @see Module#function_pass_manager
|
167
180
|
#
|
168
|
-
# @param [
|
169
|
-
|
170
|
-
def initialize(engine, mod)
|
181
|
+
# @param [Module] mod Module this pass manager belongs to.
|
182
|
+
def initialize(mod)
|
171
183
|
# LLVM Initialization
|
172
184
|
@ptr = Bindings.create_function_pass_manager_for_module(mod)
|
173
185
|
|
174
|
-
|
186
|
+
# Set the target data if the module is associated with a execution engine.
|
187
|
+
self.target_data = mod.engine.target_data if mod.engine
|
175
188
|
|
176
|
-
Bindings.initialize_function_pass_manager(@ptr)
|
189
|
+
Bindings.initialize_function_pass_manager(@ptr)
|
177
190
|
|
178
191
|
# RLTK Initialization
|
179
192
|
@enabled = Array.new
|
data/lib/rltk/cg/support.rb
CHANGED
@@ -21,6 +21,8 @@ module RLTK::CG # :nodoc:
|
|
21
21
|
# Load a shared library into memory and make its exported symbols
|
22
22
|
# available to execution engines.
|
23
23
|
#
|
24
|
+
# @LLVMECB
|
25
|
+
#
|
24
26
|
# @param [String] lib Path to the shared library to load.
|
25
27
|
def self.load_library(lib)
|
26
28
|
Bindings.load_library_permanently(lib).to_bool
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/06/13
|
4
|
+
# Description: This file defines the Target class.
|
5
|
+
|
6
|
+
############
|
7
|
+
# Requires #
|
8
|
+
############
|
9
|
+
|
10
|
+
# Ruby Language Toolkit
|
11
|
+
require 'rltk/cg/bindings'
|
12
|
+
require 'rltk/cg/triple'
|
13
|
+
|
14
|
+
#######################
|
15
|
+
# Classes and Modules #
|
16
|
+
#######################
|
17
|
+
|
18
|
+
module RLTK::CG # :nodoc:
|
19
|
+
|
20
|
+
# Class binding for the LLVM Triple class.
|
21
|
+
class Target
|
22
|
+
include BindingClass
|
23
|
+
|
24
|
+
# @return [Triple] Triple object for this target.
|
25
|
+
attr_reader :triple
|
26
|
+
|
27
|
+
# @return [Target] Target object for the host architecture.
|
28
|
+
def self.host
|
29
|
+
@host ||= self.new(Triple.host)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Create an object representing a particular code generation target.
|
33
|
+
# You can create a target either from a string or a Triple.
|
34
|
+
#
|
35
|
+
# @param [Triple, String] overloaded Object describing the target.
|
36
|
+
def initialize(overloaded)
|
37
|
+
@ptr, @triple =
|
38
|
+
case overloaded
|
39
|
+
when String then [Bindings.get_target_from_string(overloaded), Triple.new(overloaded)]
|
40
|
+
when Triple then [Bindings.get_target_from_triple(overloaded), overloaded]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# This class represents data about a specific architecture. Currently it
|
46
|
+
# is for internal use only and should not be instantiated by users.
|
47
|
+
class TargetData
|
48
|
+
include BindingClass
|
49
|
+
|
50
|
+
# @param [FFI::Pointer] ptr
|
51
|
+
def initialize(ptr)
|
52
|
+
@ptr = ptr
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# This class represents a specific architecture that wil be targeted by
|
57
|
+
# LLVM's compilation process.
|
58
|
+
class TargetMachine
|
59
|
+
include BindingClass
|
60
|
+
|
61
|
+
# Convert an array of strings representing features of a target
|
62
|
+
# machine into a single string.
|
63
|
+
#
|
64
|
+
# @param [Array<String>] features Strings representing features of a target machine.
|
65
|
+
#
|
66
|
+
# @return [String] A single string representing all of the given features.
|
67
|
+
def self.build_feature_string(features)
|
68
|
+
strings_ptr = FFI::MemoryPointer.new(:pointer, features.length)
|
69
|
+
strings_ptr.write_array_of_pointer(features.map { |str| FFI::MemoryPointer.from_string(str) })
|
70
|
+
|
71
|
+
Bindings.build_features_string(strings_ptr, features.length)
|
72
|
+
end
|
73
|
+
|
74
|
+
# @return [TargetMachine] TargetMachine representation of the host machine.
|
75
|
+
def self.host
|
76
|
+
@host ||= self.new(Target.host)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Create a new object describing a target machine.
|
80
|
+
#
|
81
|
+
# @see Bindings._enum_reloc_model_
|
82
|
+
# @see Bindings._enum_code_model_
|
83
|
+
#
|
84
|
+
# @param [Target] target Target description.
|
85
|
+
# @param [String] mcpu Specific CPU type to target.
|
86
|
+
# @param [Array<String>, String] features Features present for this target machine.
|
87
|
+
# @param [Symbol] reloc_model Code relocation model.
|
88
|
+
# @param [Symbol] code_model Code generation model.
|
89
|
+
def initialize(target, mcpu = '', features = '', reloc_model = :default, code_model = :default)
|
90
|
+
# Just to make things easier on developers.
|
91
|
+
reloc_model = :default_rmodel if reloc_model == :default
|
92
|
+
code_model = :default_cmodel if code_model == :default
|
93
|
+
|
94
|
+
# Convert the features parameter if necessary.
|
95
|
+
features = TargetMachine.build_feature_string(features) if features.is_a?(Array)
|
96
|
+
|
97
|
+
@ptr = Bindings.create_target_machine(target, target.triple.to_s, mcpu, features, reloc_model, code_model)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|