1 /* src/vm/jit/jit.cpp - Just-In-Time compiler
3 Copyright (C) 1996-2011
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 #include "mm/memory.hpp"
37 #include "native/native.hpp"
39 #include "toolbox/logging.hpp"
41 #include "threads/mutex.hpp"
43 #include "vm/class.hpp"
44 #include "vm/global.h"
45 #include "vm/globals.hpp"
46 #include "vm/hook.hpp"
47 #include "vm/initialize.hpp"
48 #include "vm/loader.hpp"
49 #include "vm/method.hpp"
50 #include "vm/options.h"
51 #include "vm/rt-timing.h"
52 #include "vm/statistics.h"
54 #include "vm/jit/asmpart.h"
56 #include "vm/jit/cfg.h"
58 #include "vm/jit/codegen-common.hpp"
59 #include "vm/jit/disass.h"
60 #include "vm/jit/dseg.h"
61 #include "vm/jit/jit.hpp"
62 #include "vm/jit/parse.hpp"
63 #include "vm/jit/reg.h"
65 #include "vm/jit/show.hpp"
66 #include "vm/jit/stack.h"
67 #include "vm/jit/stubs.hpp"
69 #include "vm/jit/allocator/simplereg.h"
70 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
71 # include "vm/jit/allocator/lsra.h"
74 #if defined(ENABLE_SSA)
75 # include "vm/jit/optimizing/lsra.h"
76 # include "vm/jit/optimizing/ssa.h"
79 #if defined(ENABLE_INLINING)
80 # include "vm/jit/inline/inline.hpp"
83 #include "vm/jit/ir/bytecode.h"
85 #include "vm/jit/loop/analyze.h"
86 #include "vm/jit/loop/graph.h"
87 #include "vm/jit/loop/loop.h"
89 #if defined(ENABLE_IFCONV)
90 # include "vm/jit/optimizing/ifconv.h"
93 #include "vm/jit/optimizing/reorder.h"
95 #if defined(ENABLE_PYTHON)
96 # include "vm/jit/python.h"
99 #include "vm/jit/verify/typecheck.hpp"
102 /* debug macros ***************************************************************/
105 #define DEBUG_JIT_COMPILEVERBOSE(x) \
107 if (compileverbose) { \
108 log_message_method(x, m); \
112 #define DEBUG_JIT_COMPILEVERBOSE(x) /* nothing */
116 # define TRACECOMPILERCALLS() \
118 if (opt_TraceCompilerCalls) { \
120 log_print("[JIT compiler started: method="); \
127 # define TRACECOMPILERCALLS()
131 /* jit_init ********************************************************************
133 Initializes the JIT subsystem.
135 *******************************************************************************/
139 TRACESUBSYSTEMINITIALIZATION("jit_init");
141 #if defined(ENABLE_JIT)
142 /* initialize stack analysis subsystem */
147 /* initialize show subsystem */
153 /* initialize codegen subsystem */
157 /* initialize code subsystem */
161 /* Machine dependent initialization. */
163 #if defined(ENABLE_JIT)
164 # if defined(ENABLE_INTRP)
176 /* jit_close *******************************************************************
178 Close the JIT subsystem.
180 *******************************************************************************/
188 /* dummy function, used when there is no JavaVM code available */
190 static u1 *do_nothing_function(void)
196 /* jit_jitdata_new *************************************************************
198 Allocates and initalizes a new jitdata structure.
200 *******************************************************************************/
202 jitdata *jit_jitdata_new(methodinfo *m)
207 /* allocate jitdata structure and fill it */
209 jd = (jitdata*) DumpMemory::allocate(sizeof(jitdata));
212 jd->cd = (codegendata*) DumpMemory::allocate(sizeof(codegendata));
213 jd->rd = (registerdata*) DumpMemory::allocate(sizeof(registerdata));
214 #if defined(ENABLE_LOOP)
215 jd->ld = (loopdata*) DumpMemory::allocate(sizeof(loopdata));
218 /* Allocate codeinfo memory from the heap as we need to keep them. */
220 code = code_codeinfo_new(m);
222 /* Set codeinfo flags. */
224 #if defined(ENABLE_THREADS)
225 if (checksync && (m->flags & ACC_SYNCHRONIZED))
226 code_flag_synchronized(code);
228 if (checksync && (m->flags & ACC_SYNCHRONIZED))
229 code_unflag_leafmethod(code);
232 code_flag_leafmethod(code);
234 /* initialize variables */
238 jd->exceptiontable = NULL;
239 jd->exceptiontablelength = 0;
241 jd->branchtoentry = false;
242 jd->branchtoend = false;
244 jd->returnblock = NULL;
245 jd->maxlocals = m->maxlocals;
251 /* jit_compile *****************************************************************
253 Translates one method to machine code.
255 *******************************************************************************/
257 static u1 *jit_compile_intern(jitdata *jd);
259 u1 *jit_compile(methodinfo *m)
264 STATISTICS(count_jit_calls++);
266 /* Initialize the static function's class. */
268 /* ATTENTION: This MUST be done before the method lock is aquired,
269 otherwise we could run into a deadlock with <clinit>'s that
270 call static methods of it's own class. */
272 if ((m->flags & ACC_STATIC) && !(m->clazz->state & CLASS_INITIALIZED)) {
275 log_message_class("Initialize class ", m->clazz);
278 if (!initialize_class(m->clazz))
281 /* check if the method has been compiled during initialization */
283 if ((m->code != NULL) && (m->code->entrypoint != NULL))
284 return m->code->entrypoint;
287 /* enter a monitor on the method */
291 /* if method has been already compiled return immediately */
293 if (m->code != NULL) {
296 assert(m->code->entrypoint);
297 return m->code->entrypoint;
300 TRACECOMPILERCALLS();
302 STATISTICS(count_methods++);
304 #if defined(ENABLE_STATISTICS)
307 if (opt_getcompilingtime)
308 compilingtime_start();
311 // Create new dump memory area.
314 /* create jitdata structure */
316 jd = jit_jitdata_new(m);
318 /* set the flags for the current JIT run */
320 jd->flags = JITDATA_FLAG_PARSE;
322 #if defined(ENABLE_VERIFIER)
324 jd->flags |= JITDATA_FLAG_VERIFY;
327 #if defined(ENABLE_PROFILING)
329 jd->flags |= JITDATA_FLAG_INSTRUMENT;
332 #if defined(ENABLE_IFCONV)
334 jd->flags |= JITDATA_FLAG_IFCONV;
337 #if defined(ENABLE_INLINING) && defined(ENABLE_INLINING_DEBUG)
338 if (opt_Inline && opt_InlineAll)
339 jd->flags |= JITDATA_FLAG_INLINE;
342 if (opt_showintermediate)
343 jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
345 if (opt_showdisassemble)
346 jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
349 jd->flags |= JITDATA_FLAG_VERBOSECALL;
351 #if defined(ENABLE_REPLACEMENT) && defined(ENABLE_INLINING)
352 if (opt_Inline && (jd->m->hitcountdown > 0) && (jd->code->optlevel == 0)) {
353 jd->flags |= JITDATA_FLAG_COUNTDOWN;
357 #if defined(ENABLE_JIT)
358 # if defined(ENABLE_INTRP)
361 /* initialize the register allocator */
367 /* setup the codegendata memory */
371 /* now call internal compile function */
373 r = jit_compile_intern(jd);
376 /* We had an exception! Finish stuff here if necessary. */
378 /* release codeinfo */
380 code_codeinfo_free(jd->code);
383 DEBUG_JIT_COMPILEVERBOSE("Running: ");
386 #if defined(ENABLE_STATISTICS)
389 if (opt_getcompilingtime)
390 compilingtime_stop();
393 // Hook point just after code was generated.
394 Hook::jit_generated(m, m->code);
396 /* leave the monitor */
400 /* return pointer to the methods entry point */
406 /* jit_recompile ***************************************************************
408 Recompiles a Java method.
410 *******************************************************************************/
412 u1 *jit_recompile(methodinfo *m)
418 /* check for max. optimization level */
420 optlevel = (m->code) ? m->code->optlevel : 0;
424 /* log_message_method("not recompiling: ", m); */
429 DEBUG_JIT_COMPILEVERBOSE("Recompiling start: ");
431 STATISTICS(count_jit_calls++);
433 #if defined(ENABLE_STATISTICS)
436 if (opt_getcompilingtime)
437 compilingtime_start();
440 // Create new dump memory area.
443 /* create jitdata structure */
445 jd = jit_jitdata_new(m);
447 /* set the current optimization level to the previous one plus 1 */
449 jd->code->optlevel = optlevel + 1;
451 /* get the optimization flags for the current JIT run */
453 #if defined(ENABLE_VERIFIER)
454 jd->flags |= JITDATA_FLAG_VERIFY;
457 /* jd->flags |= JITDATA_FLAG_REORDER; */
458 if (opt_showintermediate)
459 jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
460 if (opt_showdisassemble)
461 jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
463 jd->flags |= JITDATA_FLAG_VERBOSECALL;
465 #if defined(ENABLE_INLINING)
467 jd->flags |= JITDATA_FLAG_INLINE;
470 #if defined(ENABLE_JIT)
471 # if defined(ENABLE_INTRP)
474 /* initialize the register allocator */
479 /* setup the codegendata memory */
483 /* now call internal compile function */
485 r = jit_compile_intern(jd);
488 /* We had an exception! Finish stuff here if necessary. */
490 /* release codeinfo */
492 code_codeinfo_free(jd->code);
495 #if defined(ENABLE_STATISTICS)
498 if (opt_getcompilingtime)
499 compilingtime_stop();
502 // Hook point just after code was generated.
503 Hook::jit_generated(m, m->code);
505 DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
507 /* return pointer to the methods entry point */
512 #if defined(ENABLE_PM_HACKS)
513 #include "vm/jit/jit_pm_1.inc"
516 /* jit_compile_intern **********************************************************
518 Static internal function which does the actual compilation.
520 *******************************************************************************/
522 static u1 *jit_compile_intern(jitdata *jd)
528 #if defined(ENABLE_RT_TIMING)
529 struct timespec time_start,time_checks,time_parse,time_stack,
530 time_typecheck,time_loop,time_ifconv,time_alloc,
534 RT_TIMING_GET_TIME(time_start);
536 /* get required compiler data */
538 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
545 #if defined(ENABLE_DEBUG_FILTER)
546 show_filters_apply(jd->m);
549 // Handle native methods and create a native stub.
550 if (m->flags & ACC_NATIVE) {
551 NativeMethods& nm = VM::get_current()->get_nativemethods();
552 void* f = nm.resolve_method(m);
557 code = NativeStub::generate(m, (functionptr) f);
559 /* Native methods are never recompiled. */
565 return code->entrypoint;
568 /* if there is no javacode, print error message and return empty method */
570 if (m->jcode == NULL) {
571 DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
573 code->entrypoint = (u1 *) (ptrint) do_nothing_function;
576 return code->entrypoint; /* return empty method */
579 #if defined(ENABLE_STATISTICS)
581 count_javacodesize += m->jcodelength + 18;
582 count_tryblocks += jd->exceptiontablelength;
583 count_javaexcsize += jd->exceptiontablelength * SIZEOF_VOID_P;
587 RT_TIMING_GET_TIME(time_checks);
589 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
590 /* Code for Sun's OpenJDK (see
591 hotspot/src/share/vm/classfile/verifier.cpp
592 (Verifier::is_eligible_for_verification)): Don't verify
593 dynamically-generated bytecodes. */
595 # if defined(ENABLE_VERIFIER)
596 if (class_issubclass(m->clazz, class_sun_reflect_MagicAccessorImpl))
597 jd->flags &= ~JITDATA_FLAG_VERIFY;
601 /* call the compiler passes ***********************************************/
603 DEBUG_JIT_COMPILEVERBOSE("Parsing: ");
605 /* call parse pass */
608 DEBUG_JIT_COMPILEVERBOSE("Exception while parsing: ");
612 RT_TIMING_GET_TIME(time_parse);
614 DEBUG_JIT_COMPILEVERBOSE("Parsing done: ");
616 #if defined(ENABLE_JIT)
617 # if defined(ENABLE_INTRP)
620 DEBUG_JIT_COMPILEVERBOSE("Analysing: ");
622 /* call stack analysis pass */
624 if (!stack_analyse(jd)) {
625 DEBUG_JIT_COMPILEVERBOSE("Exception while analysing: ");
629 RT_TIMING_GET_TIME(time_stack);
631 DEBUG_JIT_COMPILEVERBOSE("Analysing done: ");
633 #ifdef ENABLE_VERIFIER
634 if (JITDATA_HAS_FLAG_VERIFY(jd)) {
635 DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
637 /* call typecheck pass */
638 if (!typecheck(jd)) {
639 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking: ");
644 DEBUG_JIT_COMPILEVERBOSE("Typechecking done: ");
647 RT_TIMING_GET_TIME(time_typecheck);
649 #if defined(ENABLE_LOOP)
654 jit_renumber_basicblocks(jd);
657 RT_TIMING_GET_TIME(time_loop);
659 #if defined(ENABLE_IFCONV)
660 if (JITDATA_HAS_FLAG_IFCONV(jd)) {
661 if (!ifconv_static(jd))
663 jit_renumber_basicblocks(jd);
666 RT_TIMING_GET_TIME(time_ifconv);
670 #if defined(ENABLE_INLINING) && (!defined(ENABLE_ESCAPE) || 1)
671 if (JITDATA_HAS_FLAG_INLINE(jd)) {
672 if (!inline_inline(jd))
677 #if defined(ENABLE_SSA)
679 fix_exception_handlers(jd);
683 /* Build the CFG. This has to be done after stack_analyse, as
684 there happens the JSR elimination. */
689 #if defined(ENABLE_PROFILING)
690 /* Basic block reordering. I think this should be done after
691 if-conversion, as we could lose the ability to do the
694 if (JITDATA_HAS_FLAG_REORDER(jd)) {
697 jit_renumber_basicblocks(jd);
701 #if defined(ENABLE_PM_HACKS)
702 #include "vm/jit/jit_pm_2.inc"
704 DEBUG_JIT_COMPILEVERBOSE("Allocating registers: ");
706 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
707 /* allocate registers */
712 STATISTICS(count_methods_allocated_by_lsra++);
715 # endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
716 #if defined(ENABLE_SSA)
717 /* allocate registers */
720 jd->code->optlevel > 0)
721 /* strncmp(jd->m->name->text, "hottie", 6) == 0*/
722 /*&& jd->exceptiontablelength == 0*/
724 /*printf("=== %s ===\n", jd->m->name->text);*/
725 jd->ls = (lsradata*) DumpMemory::allocate(sizeof(lsradata));
728 /*lsra(jd);*/ regalloc(jd);
729 /*eliminate_subbasicblocks(jd);*/
730 STATISTICS(count_methods_allocated_by_lsra++);
733 # endif /* defined(ENABLE_SSA) */
735 STATISTICS(count_locals_conflicts += (jd->maxlocals - 1) * (jd->maxlocals));
740 STATISTICS(simplereg_make_statistics(jd));
742 DEBUG_JIT_COMPILEVERBOSE("Allocating registers done: ");
743 # if defined(ENABLE_INTRP)
746 #endif /* defined(ENABLE_JIT) */
747 RT_TIMING_GET_TIME(time_alloc);
749 #if defined(ENABLE_PROFILING)
750 /* Allocate memory for basic block profiling information. This
751 _must_ be done after loop optimization and register allocation,
752 since they can change the basic block count. */
754 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
755 code->basicblockcount = jd->basicblockcount;
756 code->bbfrequency = MNEW(u4, jd->basicblockcount);
760 DEBUG_JIT_COMPILEVERBOSE("Generating code: ");
762 /* now generate the machine code */
764 #if defined(ENABLE_JIT)
765 # if defined(ENABLE_INTRP)
767 #if defined(ENABLE_VERIFIER)
769 DEBUG_JIT_COMPILEVERBOSE("Typechecking (stackbased): ");
771 if (!typecheck_stackbased(jd)) {
772 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking (stackbased): ");
777 if (!intrp_codegen(jd)) {
778 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
785 if (!codegen_generate(jd)) {
786 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
792 if (!intrp_codegen(jd)) {
793 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
798 RT_TIMING_GET_TIME(time_codegen);
800 DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
802 #if !defined(NDEBUG) && defined(ENABLE_REPLACEMENT)
803 /* activate replacement points inside newly created code */
805 if (opt_TestReplacement)
806 replace_activate_replacement_points(code, false);
810 #if defined(ENABLE_DEBUG_FILTER)
811 if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
814 /* intermediate and assembly code listings */
816 if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
817 show_method(jd, SHOW_CODE);
819 else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
820 # if defined(ENABLE_DISASSEMBLER)
821 DISASSEMBLE(code->entrypoint,
822 code->entrypoint + (code->mcodelength - cd->dseglen));
826 if (opt_showddatasegment)
831 /* switch to the newly generated code */
834 assert(code->entrypoint);
836 /* add the current compile version to the methodinfo */
838 code->prev = m->code;
841 RT_TIMING_TIME_DIFF(time_start,time_checks,RT_TIMING_JIT_CHECKS);
842 RT_TIMING_TIME_DIFF(time_checks,time_parse,RT_TIMING_JIT_PARSE);
843 RT_TIMING_TIME_DIFF(time_parse,time_stack,RT_TIMING_JIT_STACK);
844 RT_TIMING_TIME_DIFF(time_stack,time_typecheck,RT_TIMING_JIT_TYPECHECK);
845 RT_TIMING_TIME_DIFF(time_typecheck,time_loop,RT_TIMING_JIT_LOOP);
846 RT_TIMING_TIME_DIFF(time_loop,time_alloc,RT_TIMING_JIT_ALLOC);
847 RT_TIMING_TIME_DIFF(time_alloc,time_codegen,RT_TIMING_JIT_CODEGEN);
848 RT_TIMING_TIME_DIFF(time_start,time_codegen,RT_TIMING_JIT_TOTAL);
850 /* return pointer to the methods entry point */
852 return code->entrypoint;
856 /* jit_invalidate_code *********************************************************
858 Mark the compiled code of the given method as invalid and take care that
859 it is replaced if necessary.
861 XXX Not fully implemented, yet.
863 *******************************************************************************/
865 void jit_invalidate_code(methodinfo *m)
871 if (code == NULL || code_is_invalid(code))
874 code_flag_invalid(code);
876 /* activate mappable replacement points */
878 #if defined(ENABLE_REPLACEMENT)
879 replace_activate_replacement_points(code, true);
881 vm_abort("invalidating code only works with ENABLE_REPLACEMENT");
886 /* jit_request_optimization ****************************************************
888 Request optimization of the given method. If the code of the method is
889 unoptimized, it will be invalidated, so the next jit_get_current_code(m)
890 triggers an optimized recompilation.
891 If the method is already optimized, this function does nothing.
894 m................the method
896 *******************************************************************************/
898 void jit_request_optimization(methodinfo *m)
904 if (code && code->optlevel == 0)
905 jit_invalidate_code(m);
909 /* jit_get_current_code ********************************************************
911 Get the currently valid code for the given method. If there is no valid
912 code, (re)compile the method.
915 m................the method
918 the codeinfo* for the current code, or
919 NULL if an exception has been thrown during recompilation.
921 *******************************************************************************/
923 codeinfo *jit_get_current_code(methodinfo *m)
927 /* if we have valid code, return it */
929 if (m->code && !code_is_invalid(m->code))
932 /* otherwise: recompile */
934 if (!jit_recompile(m))
943 /* jit_asm_compile *************************************************************
945 This method is called from asm_vm_call_method and does:
947 - create stackframe info for exceptions
949 - patch the entrypoint of the method into the calculated address in
951 - flushes the instruction cache.
953 *******************************************************************************/
955 #if defined(ENABLE_JIT)
956 #if !defined(JIT_COMPILER_VIA_SIGNAL)
958 void* jit_asm_compile(methodinfo *m, void* mptr, void* sp, void* ra)
960 stackframeinfo_t sfi;
965 /* create the stackframeinfo (subtract 1 from RA as it points to the */
966 /* instruction after the call) */
968 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ((uint8_t*) ra) - 1);
970 /* actually compile the method */
972 entrypoint = jit_compile(m);
974 /* remove the stackframeinfo */
976 stacktrace_stackframeinfo_remove(&sfi);
978 /* there was a problem during compilation */
980 if (entrypoint == NULL)
983 /* get the method patch address */
985 pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
987 /* patch the method entry point */
991 *p = (uintptr_t) entrypoint;
993 /* flush the instruction cache */
995 md_icacheflush(pa, SIZEOF_VOID_P);
1002 /* jit_compile_handle **********************************************************
1004 This method is called from the appropriate signal handler which
1005 handles compiler-traps and does the following:
1007 - compile the method
1008 - patch the entrypoint of the method into the calculated address in
1010 - flush the instruction cache
1012 *******************************************************************************/
1014 void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
1016 void *newpv; /* new compiled method PV */
1017 void *pa; /* patch address */
1018 uintptr_t *p; /* convenience pointer */
1020 /* Compile the method. */
1022 newpv = jit_compile(m);
1024 /* There was a problem during compilation. */
1029 /* Get the method patch address. */
1031 pa = md_jit_method_patch_address(pv, ra, mptr);
1033 /* Patch the method entry point. */
1035 p = (uintptr_t *) pa;
1037 *p = (uintptr_t) newpv;
1039 #if !defined(JIT_COMPILER_VIA_SIGNAL)
1040 /* Flush both caches. */
1041 /* This might have been necessary before we had the compiler trap, but now
1042 * it's not. I don't care enough about the (broken) non-signal case to
1043 * investigate this. */
1045 md_cacheflush(pa, SIZEOF_VOID_P);
1050 #endif /* defined(ENABLE_JIT) */
1053 /* jit_complement_condition ****************************************************
1055 Returns the complement of the passed conditional instruction.
1057 We use the order of the different conditions, e.g.:
1062 If the passed opcode is odd, we simply add 1 to get the complement.
1063 If the opcode is even, we subtract 1.
1070 *******************************************************************************/
1072 s4 jit_complement_condition(s4 opcode)
1076 return ICMD_IFNONNULL;
1078 case ICMD_IFNONNULL:
1082 /* check if opcode is odd */
1092 /* jit_renumber_basicblocks ****************************************************
1094 Set the ->nr of all blocks so it increases when traversing ->next.
1097 jitdata..........the current jitdata
1099 *******************************************************************************/
1101 void jit_renumber_basicblocks(jitdata *jd)
1107 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1111 /* we have one block more than jd->basicblockcount (the end marker) */
1113 assert(nr == jd->basicblockcount + 1);
1117 /* jit_check_basicblock_numbers ************************************************
1119 Assert that the ->nr of the first block is zero and increases by 1 each
1120 time ->next is traversed.
1121 This function should be called before any analysis that relies on
1122 the basicblock numbers.
1125 jitdata..........the current jitdata
1127 NOTE: Aborts with an assertion if the condition is not met!
1129 *******************************************************************************/
1131 #if !defined(NDEBUG)
1132 void jit_check_basicblock_numbers(jitdata *jd)
1138 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1139 assert(bptr->nr == nr);
1143 /* we have one block more than jd->basicblockcount (the end marker) */
1145 assert(nr == jd->basicblockcount + 1);
1147 #endif /* !defined(NDEBUG) */
1151 * These are local overrides for various environment variables in Emacs.
1152 * Please do not remove this and leave it at the end of the file, where
1153 * Emacs will automagically detect them.
1154 * ---------------------------------------------------------------------
1157 * indent-tabs-mode: t
1161 * vim:noexpandtab:sw=4:ts=4: