Mercurial > hg > truffle
annotate src/share/vm/shark/sharkBuilder.cpp @ 7090:05ce1defa4f9
Common out some parts of UnsafeLoad/Store in UnsafeAccess
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Thu, 29 Nov 2012 13:24:08 +0100 |
parents | da91efe96a93 |
children | 2cd5e15048e6 |
rev | line source |
---|---|
1692 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1972
diff
changeset
|
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. |
1692 | 3 * Copyright 2008, 2009, 2010 Red Hat, Inc. |
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 * | |
6 * This code is free software; you can redistribute it and/or modify it | |
7 * under the terms of the GNU General Public License version 2 only, as | |
8 * published by the Free Software Foundation. | |
9 * | |
10 * This code is distributed in the hope that it will be useful, but WITHOUT | |
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 * version 2 for more details (a copy is included in the LICENSE file that | |
14 * accompanied this code). | |
15 * | |
16 * You should have received a copy of the GNU General Public License version | |
17 * 2 along with this work; if not, write to the Free Software Foundation, | |
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 * | |
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
21 * or visit www.oracle.com if you need additional information or have any | |
22 * questions. | |
23 * | |
24 */ | |
25 | |
1972 | 26 #include "precompiled.hpp" |
27 #include "ci/ciMethod.hpp" | |
28 #include "memory/resourceArea.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1972
diff
changeset
|
29 #include "oops/method.hpp" |
1972 | 30 #include "runtime/os.hpp" |
31 #include "runtime/synchronizer.hpp" | |
32 #include "runtime/thread.hpp" | |
33 #include "shark/llvmHeaders.hpp" | |
34 #include "shark/llvmValue.hpp" | |
35 #include "shark/sharkBuilder.hpp" | |
36 #include "shark/sharkContext.hpp" | |
37 #include "shark/sharkRuntime.hpp" | |
38 #include "utilities/debug.hpp" | |
1692 | 39 |
40 using namespace llvm; | |
41 | |
42 SharkBuilder::SharkBuilder(SharkCodeBuffer* code_buffer) | |
43 : IRBuilder<>(SharkContext::current()), | |
44 _code_buffer(code_buffer) { | |
45 } | |
46 | |
47 // Helpers for accessing structures | |
48 Value* SharkBuilder::CreateAddressOfStructEntry(Value* base, | |
49 ByteSize offset, | |
50 const Type* type, | |
51 const char* name) { | |
52 return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name); | |
53 } | |
54 | |
55 LoadInst* SharkBuilder::CreateValueOfStructEntry(Value* base, | |
56 ByteSize offset, | |
57 const Type* type, | |
58 const char* name) { | |
59 return CreateLoad( | |
60 CreateAddressOfStructEntry( | |
61 base, offset, PointerType::getUnqual(type)), | |
62 name); | |
63 } | |
64 | |
65 // Helpers for accessing arrays | |
66 | |
67 LoadInst* SharkBuilder::CreateArrayLength(Value* arrayoop) { | |
68 return CreateValueOfStructEntry( | |
69 arrayoop, in_ByteSize(arrayOopDesc::length_offset_in_bytes()), | |
70 SharkType::jint_type(), "length"); | |
71 } | |
72 | |
73 Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, | |
74 const Type* element_type, | |
75 int element_bytes, | |
76 ByteSize base_offset, | |
77 Value* index, | |
78 const char* name) { | |
79 Value* offset = CreateIntCast(index, SharkType::intptr_type(), false); | |
80 if (element_bytes != 1) | |
81 offset = CreateShl( | |
82 offset, | |
83 LLVMValue::intptr_constant(exact_log2(element_bytes))); | |
84 offset = CreateAdd( | |
85 LLVMValue::intptr_constant(in_bytes(base_offset)), offset); | |
86 | |
87 return CreateIntToPtr( | |
88 CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset), | |
89 PointerType::getUnqual(element_type), | |
90 name); | |
91 } | |
92 | |
93 Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, | |
94 BasicType basic_type, | |
95 ByteSize base_offset, | |
96 Value* index, | |
97 const char* name) { | |
98 return CreateArrayAddress( | |
99 arrayoop, | |
100 SharkType::to_arrayType(basic_type), | |
101 type2aelembytes(basic_type), | |
102 base_offset, index, name); | |
103 } | |
104 | |
105 Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, | |
106 BasicType basic_type, | |
107 Value* index, | |
108 const char* name) { | |
109 return CreateArrayAddress( | |
110 arrayoop, basic_type, | |
111 in_ByteSize(arrayOopDesc::base_offset_in_bytes(basic_type)), | |
112 index, name); | |
113 } | |
114 | |
115 // Helpers for creating intrinsics and external functions. | |
116 | |
117 const Type* SharkBuilder::make_type(char type, bool void_ok) { | |
118 switch (type) { | |
119 // Primitive types | |
120 case 'c': | |
121 return SharkType::jbyte_type(); | |
122 case 'i': | |
123 return SharkType::jint_type(); | |
124 case 'l': | |
125 return SharkType::jlong_type(); | |
126 case 'x': | |
127 return SharkType::intptr_type(); | |
128 case 'f': | |
129 return SharkType::jfloat_type(); | |
130 case 'd': | |
131 return SharkType::jdouble_type(); | |
132 | |
133 // Pointers to primitive types | |
134 case 'C': | |
135 case 'I': | |
136 case 'L': | |
137 case 'X': | |
138 case 'F': | |
139 case 'D': | |
140 return PointerType::getUnqual(make_type(tolower(type), false)); | |
141 | |
142 // VM objects | |
143 case 'T': | |
144 return SharkType::thread_type(); | |
145 case 'M': | |
146 return PointerType::getUnqual(SharkType::monitor_type()); | |
147 case 'O': | |
148 return SharkType::oop_type(); | |
149 | |
150 // Miscellaneous | |
151 case 'v': | |
152 assert(void_ok, "should be"); | |
153 return SharkType::void_type(); | |
154 case '1': | |
155 return SharkType::bit_type(); | |
156 | |
157 default: | |
158 ShouldNotReachHere(); | |
159 } | |
160 } | |
161 | |
162 const FunctionType* SharkBuilder::make_ftype(const char* params, | |
163 const char* ret) { | |
164 std::vector<const Type*> param_types; | |
165 for (const char* c = params; *c; c++) | |
166 param_types.push_back(make_type(*c, false)); | |
167 | |
168 assert(strlen(ret) == 1, "should be"); | |
169 const Type *return_type = make_type(*ret, true); | |
170 | |
171 return FunctionType::get(return_type, param_types, false); | |
172 } | |
173 | |
174 // Create an object representing an intrinsic or external function by | |
175 // referencing the symbol by name. This is the LLVM-style approach, | |
176 // but it cannot be used on functions within libjvm.so its symbols | |
177 // are not exported. Note that you cannot make this work simply by | |
178 // exporting the symbols, as some symbols have the same names as | |
179 // symbols in the standard libraries (eg, atan2, fabs) and would | |
180 // obscure them were they visible. | |
181 Value* SharkBuilder::make_function(const char* name, | |
182 const char* params, | |
183 const char* ret) { | |
184 return SharkContext::current().get_external(name, make_ftype(params, ret)); | |
185 } | |
186 | |
187 // Create an object representing an external function by inlining a | |
188 // function pointer in the code. This is not the LLVM way, but it's | |
189 // the only way to access functions in libjvm.so and functions like | |
190 // __kernel_dmb on ARM which is accessed via an absolute address. | |
191 Value* SharkBuilder::make_function(address func, | |
192 const char* params, | |
193 const char* ret) { | |
194 return CreateIntToPtr( | |
195 LLVMValue::intptr_constant((intptr_t) func), | |
196 PointerType::getUnqual(make_ftype(params, ret))); | |
197 } | |
198 | |
199 // VM calls | |
200 | |
201 Value* SharkBuilder::find_exception_handler() { | |
202 return make_function( | |
203 (address) SharkRuntime::find_exception_handler, "TIi", "i"); | |
204 } | |
205 | |
206 Value* SharkBuilder::monitorenter() { | |
207 return make_function((address) SharkRuntime::monitorenter, "TM", "v"); | |
208 } | |
209 | |
210 Value* SharkBuilder::monitorexit() { | |
211 return make_function((address) SharkRuntime::monitorexit, "TM", "v"); | |
212 } | |
213 | |
214 Value* SharkBuilder::new_instance() { | |
215 return make_function((address) SharkRuntime::new_instance, "Ti", "v"); | |
216 } | |
217 | |
218 Value* SharkBuilder::newarray() { | |
219 return make_function((address) SharkRuntime::newarray, "Tii", "v"); | |
220 } | |
221 | |
222 Value* SharkBuilder::anewarray() { | |
223 return make_function((address) SharkRuntime::anewarray, "Tii", "v"); | |
224 } | |
225 | |
226 Value* SharkBuilder::multianewarray() { | |
227 return make_function((address) SharkRuntime::multianewarray, "TiiI", "v"); | |
228 } | |
229 | |
230 Value* SharkBuilder::register_finalizer() { | |
231 return make_function((address) SharkRuntime::register_finalizer, "TO", "v"); | |
232 } | |
233 | |
234 Value* SharkBuilder::safepoint() { | |
235 return make_function((address) SafepointSynchronize::block, "T", "v"); | |
236 } | |
237 | |
238 Value* SharkBuilder::throw_ArithmeticException() { | |
239 return make_function( | |
240 (address) SharkRuntime::throw_ArithmeticException, "TCi", "v"); | |
241 } | |
242 | |
243 Value* SharkBuilder::throw_ArrayIndexOutOfBoundsException() { | |
244 return make_function( | |
245 (address) SharkRuntime::throw_ArrayIndexOutOfBoundsException, "TCii", "v"); | |
246 } | |
247 | |
248 Value* SharkBuilder::throw_ClassCastException() { | |
249 return make_function( | |
250 (address) SharkRuntime::throw_ClassCastException, "TCi", "v"); | |
251 } | |
252 | |
253 Value* SharkBuilder::throw_NullPointerException() { | |
254 return make_function( | |
255 (address) SharkRuntime::throw_NullPointerException, "TCi", "v"); | |
256 } | |
257 | |
258 // High-level non-VM calls | |
259 | |
260 Value* SharkBuilder::f2i() { | |
261 return make_function((address) SharedRuntime::f2i, "f", "i"); | |
262 } | |
263 | |
264 Value* SharkBuilder::f2l() { | |
265 return make_function((address) SharedRuntime::f2l, "f", "l"); | |
266 } | |
267 | |
268 Value* SharkBuilder::d2i() { | |
269 return make_function((address) SharedRuntime::d2i, "d", "i"); | |
270 } | |
271 | |
272 Value* SharkBuilder::d2l() { | |
273 return make_function((address) SharedRuntime::d2l, "d", "l"); | |
274 } | |
275 | |
276 Value* SharkBuilder::is_subtype_of() { | |
277 return make_function((address) SharkRuntime::is_subtype_of, "OO", "c"); | |
278 } | |
279 | |
280 Value* SharkBuilder::current_time_millis() { | |
281 return make_function((address) os::javaTimeMillis, "", "l"); | |
282 } | |
283 | |
284 Value* SharkBuilder::sin() { | |
285 return make_function("llvm.sin.f64", "d", "d"); | |
286 } | |
287 | |
288 Value* SharkBuilder::cos() { | |
289 return make_function("llvm.cos.f64", "d", "d"); | |
290 } | |
291 | |
292 Value* SharkBuilder::tan() { | |
293 return make_function((address) ::tan, "d", "d"); | |
294 } | |
295 | |
296 Value* SharkBuilder::atan2() { | |
297 return make_function((address) ::atan2, "dd", "d"); | |
298 } | |
299 | |
300 Value* SharkBuilder::sqrt() { | |
301 return make_function("llvm.sqrt.f64", "d", "d"); | |
302 } | |
303 | |
304 Value* SharkBuilder::log() { | |
305 return make_function("llvm.log.f64", "d", "d"); | |
306 } | |
307 | |
308 Value* SharkBuilder::log10() { | |
309 return make_function("llvm.log10.f64", "d", "d"); | |
310 } | |
311 | |
312 Value* SharkBuilder::pow() { | |
313 return make_function("llvm.pow.f64", "dd", "d"); | |
314 } | |
315 | |
316 Value* SharkBuilder::exp() { | |
317 return make_function("llvm.exp.f64", "d", "d"); | |
318 } | |
319 | |
320 Value* SharkBuilder::fabs() { | |
321 return make_function((address) ::fabs, "d", "d"); | |
322 } | |
323 | |
324 Value* SharkBuilder::unsafe_field_offset_to_byte_offset() { | |
325 extern jlong Unsafe_field_offset_to_byte_offset(jlong field_offset); | |
326 return make_function((address) Unsafe_field_offset_to_byte_offset, "l", "l"); | |
327 } | |
328 | |
329 Value* SharkBuilder::osr_migration_end() { | |
330 return make_function((address) SharedRuntime::OSR_migration_end, "C", "v"); | |
331 } | |
332 | |
333 // Semi-VM calls | |
334 | |
335 Value* SharkBuilder::throw_StackOverflowError() { | |
336 return make_function((address) ZeroStack::handle_overflow, "T", "v"); | |
337 } | |
338 | |
339 Value* SharkBuilder::uncommon_trap() { | |
340 return make_function((address) SharkRuntime::uncommon_trap, "Ti", "i"); | |
341 } | |
342 | |
343 Value* SharkBuilder::deoptimized_entry_point() { | |
344 return make_function((address) CppInterpreter::main_loop, "iT", "v"); | |
345 } | |
346 | |
347 // Native-Java transition | |
348 | |
349 Value* SharkBuilder::check_special_condition_for_native_trans() { | |
350 return make_function( | |
351 (address) JavaThread::check_special_condition_for_native_trans, | |
352 "T", "v"); | |
353 } | |
354 | |
355 // Low-level non-VM calls | |
356 | |
357 // The ARM-specific code here is to work around unimplemented | |
358 // atomic exchange and memory barrier intrinsics in LLVM. | |
359 // | |
360 // Delegating to external functions for these would normally | |
361 // incur a speed penalty, but Linux on ARM is a special case | |
362 // in that atomic operations on that platform are handled by | |
363 // external functions anyway. It would be *preferable* for | |
364 // the calls to be hidden away in LLVM, but it's not hurting | |
365 // performance so having the calls here is acceptable. | |
366 // | |
367 // If you are building Shark on a platform without atomic | |
368 // exchange and/or memory barrier intrinsics then it is only | |
369 // acceptable to mimic this approach if your platform cannot | |
370 // perform these operations without delegating to a function. | |
371 | |
372 #ifdef ARM | |
373 static jint zero_cmpxchg_int(volatile jint *ptr, jint oldval, jint newval) { | |
374 return Atomic::cmpxchg(newval, ptr, oldval); | |
375 } | |
376 #endif // ARM | |
377 | |
378 Value* SharkBuilder::cmpxchg_int() { | |
379 return make_function( | |
380 #ifdef ARM | |
381 (address) zero_cmpxchg_int, | |
382 #else | |
383 "llvm.atomic.cmp.swap.i32.p0i32", | |
384 #endif // ARM | |
385 "Iii", "i"); | |
386 } | |
387 | |
388 #ifdef ARM | |
389 static intptr_t zero_cmpxchg_ptr(volatile intptr_t* ptr, | |
390 intptr_t oldval, | |
391 intptr_t newval) { | |
392 return Atomic::cmpxchg_ptr(newval, ptr, oldval); | |
393 } | |
394 #endif // ARM | |
395 | |
396 Value* SharkBuilder::cmpxchg_ptr() { | |
397 return make_function( | |
398 #ifdef ARM | |
399 (address) zero_cmpxchg_ptr, | |
400 #else | |
401 "llvm.atomic.cmp.swap.i" LP64_ONLY("64") NOT_LP64("32") ".p0i" LP64_ONLY("64") NOT_LP64("32"), | |
402 #endif // ARM | |
403 "Xxx", "x"); | |
404 } | |
405 | |
406 Value* SharkBuilder::frame_address() { | |
407 return make_function("llvm.frameaddress", "i", "C"); | |
408 } | |
409 | |
410 Value* SharkBuilder::memory_barrier() { | |
411 return make_function( | |
412 #ifdef ARM | |
413 (address) 0xffff0fa0, // __kernel_dmb | |
414 #else | |
415 "llvm.memory.barrier", | |
416 #endif // ARM | |
417 "11111", "v"); | |
418 } | |
419 | |
420 Value* SharkBuilder::memset() { | |
421 #if SHARK_LLVM_VERSION >= 28 | |
422 // LLVM 2.8 added a fifth isVolatile field for memset | |
423 // introduced with LLVM r100304 | |
424 return make_function("llvm.memset.i32", "Cciii", "v"); | |
425 #else | |
426 return make_function("llvm.memset.i32", "Ccii", "v"); | |
427 #endif | |
428 } | |
429 | |
430 Value* SharkBuilder::unimplemented() { | |
431 return make_function((address) report_unimplemented, "Ci", "v"); | |
432 } | |
433 | |
434 Value* SharkBuilder::should_not_reach_here() { | |
435 return make_function((address) report_should_not_reach_here, "Ci", "v"); | |
436 } | |
437 | |
438 Value* SharkBuilder::dump() { | |
439 return make_function((address) SharkRuntime::dump, "Cx", "v"); | |
440 } | |
441 | |
442 // Public interface to low-level non-VM calls | |
443 | |
444 CallInst* SharkBuilder::CreateCmpxchgInt(Value* exchange_value, | |
445 Value* dst, | |
446 Value* compare_value) { | |
447 return CreateCall3(cmpxchg_int(), dst, compare_value, exchange_value); | |
448 } | |
449 | |
450 CallInst* SharkBuilder::CreateCmpxchgPtr(Value* exchange_value, | |
451 Value* dst, | |
452 Value* compare_value) { | |
453 return CreateCall3(cmpxchg_ptr(), dst, compare_value, exchange_value); | |
454 } | |
455 | |
456 CallInst* SharkBuilder::CreateGetFrameAddress() { | |
457 return CreateCall(frame_address(), LLVMValue::jint_constant(0)); | |
458 } | |
459 | |
460 CallInst *SharkBuilder::CreateMemoryBarrier(int flags) { | |
461 Value *args[] = { | |
462 LLVMValue::bit_constant((flags & BARRIER_LOADLOAD) ? 1 : 0), | |
463 LLVMValue::bit_constant((flags & BARRIER_LOADSTORE) ? 1 : 0), | |
464 LLVMValue::bit_constant((flags & BARRIER_STORELOAD) ? 1 : 0), | |
465 LLVMValue::bit_constant((flags & BARRIER_STORESTORE) ? 1 : 0), | |
466 LLVMValue::bit_constant(1)}; | |
467 | |
468 return CreateCall(memory_barrier(), args, args + 5); | |
469 } | |
470 | |
471 CallInst* SharkBuilder::CreateMemset(Value* dst, | |
472 Value* value, | |
473 Value* len, | |
474 Value* align) { | |
475 #if SHARK_LLVM_VERSION >= 28 | |
476 return CreateCall5(memset(), dst, value, len, align, | |
477 LLVMValue::jint_constant(0)); | |
478 #else | |
479 return CreateCall4(memset(), dst, value, len, align); | |
480 #endif | |
481 } | |
482 | |
483 CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line) { | |
484 return CreateCall2( | |
485 unimplemented(), | |
486 CreateIntToPtr( | |
487 LLVMValue::intptr_constant((intptr_t) file), | |
488 PointerType::getUnqual(SharkType::jbyte_type())), | |
489 LLVMValue::jint_constant(line)); | |
490 } | |
491 | |
492 CallInst* SharkBuilder::CreateShouldNotReachHere(const char* file, int line) { | |
493 return CreateCall2( | |
494 should_not_reach_here(), | |
495 CreateIntToPtr( | |
496 LLVMValue::intptr_constant((intptr_t) file), | |
497 PointerType::getUnqual(SharkType::jbyte_type())), | |
498 LLVMValue::jint_constant(line)); | |
499 } | |
500 | |
501 #ifndef PRODUCT | |
502 CallInst* SharkBuilder::CreateDump(Value* value) { | |
503 const char *name; | |
504 if (value->hasName()) | |
505 // XXX this leaks, but it's only debug code | |
506 name = strdup(value->getName().str().c_str()); | |
507 else | |
508 name = "unnamed_value"; | |
509 | |
510 if (isa<PointerType>(value->getType())) | |
511 value = CreatePtrToInt(value, SharkType::intptr_type()); | |
512 else if (value->getType()-> | |
513 #if SHARK_LLVM_VERSION >= 27 | |
514 isIntegerTy() | |
515 #else | |
516 isInteger() | |
517 #endif | |
518 ) | |
519 value = CreateIntCast(value, SharkType::intptr_type(), false); | |
520 else | |
521 Unimplemented(); | |
522 | |
523 return CreateCall2( | |
524 dump(), | |
525 CreateIntToPtr( | |
526 LLVMValue::intptr_constant((intptr_t) name), | |
527 PointerType::getUnqual(SharkType::jbyte_type())), | |
528 value); | |
529 } | |
530 #endif // PRODUCT | |
531 | |
532 // HotSpot memory barriers | |
533 | |
534 void SharkBuilder::CreateUpdateBarrierSet(BarrierSet* bs, Value* field) { | |
535 if (bs->kind() != BarrierSet::CardTableModRef) | |
536 Unimplemented(); | |
537 | |
538 CreateStore( | |
539 LLVMValue::jbyte_constant(CardTableModRefBS::dirty_card), | |
540 CreateIntToPtr( | |
541 CreateAdd( | |
542 LLVMValue::intptr_constant( | |
543 (intptr_t) ((CardTableModRefBS *) bs)->byte_map_base), | |
544 CreateLShr( | |
545 CreatePtrToInt(field, SharkType::intptr_type()), | |
546 LLVMValue::intptr_constant(CardTableModRefBS::card_shift))), | |
547 PointerType::getUnqual(SharkType::jbyte_type()))); | |
548 } | |
549 | |
550 // Helpers for accessing the code buffer | |
551 | |
552 Value* SharkBuilder::code_buffer_address(int offset) { | |
553 return CreateAdd( | |
554 code_buffer()->base_pc(), | |
555 LLVMValue::intptr_constant(offset)); | |
556 } | |
557 | |
558 Value* SharkBuilder::CreateInlineOop(jobject object, const char* name) { | |
559 return CreateLoad( | |
560 CreateIntToPtr( | |
561 code_buffer_address(code_buffer()->inline_oop(object)), | |
562 PointerType::getUnqual(SharkType::oop_type())), | |
563 name); | |
564 } | |
565 | |
566 Value* SharkBuilder::CreateInlineData(void* data, | |
567 size_t size, | |
568 const Type* type, | |
569 const char* name) { | |
570 return CreateIntToPtr( | |
571 code_buffer_address(code_buffer()->inline_data(data, size)), | |
572 type, | |
573 name); | |
574 } | |
575 | |
576 // Helpers for creating basic blocks. | |
577 | |
578 BasicBlock* SharkBuilder::GetBlockInsertionPoint() const { | |
579 BasicBlock *cur = GetInsertBlock(); | |
580 | |
581 // BasicBlock::Create takes an insertBefore argument, so | |
582 // we need to find the block _after_ the current block | |
583 Function::iterator iter = cur->getParent()->begin(); | |
584 Function::iterator end = cur->getParent()->end(); | |
585 while (iter != end) { | |
586 iter++; | |
587 if (&*iter == cur) { | |
588 iter++; | |
589 break; | |
590 } | |
591 } | |
592 | |
593 if (iter == end) | |
594 return NULL; | |
595 else | |
596 return iter; | |
597 } | |
598 | |
599 BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const { | |
600 return BasicBlock::Create( | |
601 SharkContext::current(), name, GetInsertBlock()->getParent(), ip); | |
602 } |