rltk 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|