1 /* src/vm/jit/jit.c - calls the code generation functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
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.h"
37 #include "native/native.h"
39 #include "toolbox/logging.h"
41 #include "threads/lock-common.h"
44 #include "vm/global.h"
45 #include "vm/globals.hpp"
46 #include "vm/initialize.h"
47 #include "vm/loader.h"
48 #include "vm/method.h"
49 #include "vm/options.h"
50 #include "vm/rt-timing.h"
51 #include "vm/statistics.h"
53 #include "vm/jit/asmpart.h"
55 #include "vm/jit/cfg.h"
57 #include "vm/jit/codegen-common.h"
58 #include "vm/jit/disass.h"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/jit.h"
61 #include "vm/jit/parse.h"
62 #include "vm/jit/reg.h"
64 #include "vm/jit/show.h"
65 #include "vm/jit/stack.h"
67 #if defined(ENABLE_OPAGENT)
68 #include "vm/jit/oprofile-agent.hpp"
71 #include "vm/jit/allocator/simplereg.h"
72 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
73 # include "vm/jit/allocator/lsra.h"
76 #if defined(ENABLE_SSA)
77 # include "vm/jit/optimizing/lsra.h"
78 # include "vm/jit/optimizing/ssa.h"
81 #if defined(ENABLE_INLINING)
82 # include "vm/jit/inline/inline.h"
85 #include "vm/jit/ir/bytecode.h"
87 #include "vm/jit/loop/analyze.h"
88 #include "vm/jit/loop/graph.h"
89 #include "vm/jit/loop/loop.h"
91 #if defined(ENABLE_IFCONV)
92 # include "vm/jit/optimizing/ifconv.h"
95 #include "vm/jit/optimizing/reorder.h"
97 #if defined(ENABLE_PYTHON)
98 # include "vm/jit/python.h"
101 #include "vm/jit/verify/typecheck.h"
104 /* debug macros ***************************************************************/
107 #define DEBUG_JIT_COMPILEVERBOSE(x) \
109 if (compileverbose) { \
110 log_message_method(x, m); \
114 #define DEBUG_JIT_COMPILEVERBOSE(x) /* nothing */
118 # define TRACECOMPILERCALLS() \
120 if (opt_TraceCompilerCalls) { \
122 log_print("[JIT compiler started: method="); \
129 # define TRACECOMPILERCALLS()
133 /* jit_init ********************************************************************
135 Initializes the JIT subsystem.
137 *******************************************************************************/
141 TRACESUBSYSTEMINITIALIZATION("jit_init");
143 #if defined(ENABLE_JIT)
144 /* initialize stack analysis subsystem */
149 /* initialize show subsystem */
155 /* initialize codegen subsystem */
159 /* initialize code subsystem */
163 /* Machine dependent initialization. */
165 #if defined(ENABLE_JIT)
166 # if defined(ENABLE_INTRP)
176 #if defined(ENABLE_OPAGENT)
177 if (opt_EnableOpagent)
178 OprofileAgent_initialize();
183 /* jit_close *******************************************************************
185 Close the JIT subsystem.
187 *******************************************************************************/
191 #if defined(ENABLE_OPAGENT)
192 if (opt_EnableOpagent)
193 OprofileAgent_close();
198 /* dummy function, used when there is no JavaVM code available */
200 static u1 *do_nothing_function(void)
206 /* jit_jitdata_new *************************************************************
208 Allocates and initalizes a new jitdata structure.
210 *******************************************************************************/
212 jitdata *jit_jitdata_new(methodinfo *m)
217 /* allocate jitdata structure and fill it */
222 jd->cd = DNEW(codegendata);
223 jd->rd = DNEW(registerdata);
224 #if defined(ENABLE_LOOP)
225 jd->ld = DNEW(loopdata);
228 /* Allocate codeinfo memory from the heap as we need to keep them. */
230 code = code_codeinfo_new(m);
232 /* Set codeinfo flags. */
234 #if defined(ENABLE_THREADS)
235 if (checksync && (m->flags & ACC_SYNCHRONIZED))
236 code_flag_synchronized(code);
238 if (checksync && (m->flags & ACC_SYNCHRONIZED))
239 code_unflag_leafmethod(code);
242 code_flag_leafmethod(code);
244 /* initialize variables */
248 jd->exceptiontable = NULL;
249 jd->exceptiontablelength = 0;
251 jd->branchtoentry = false;
252 jd->branchtoend = false;
254 jd->returnblock = NULL;
255 jd->maxlocals = m->maxlocals;
261 /* jit_compile *****************************************************************
263 Translates one method to machine code.
265 *******************************************************************************/
267 static u1 *jit_compile_intern(jitdata *jd);
269 u1 *jit_compile(methodinfo *m)
275 STATISTICS(count_jit_calls++);
277 /* Initialize the static function's class. */
279 /* ATTENTION: This MUST be done before the method lock is aquired,
280 otherwise we could run into a deadlock with <clinit>'s that
281 call static methods of it's own class. */
283 if ((m->flags & ACC_STATIC) && !(m->clazz->state & CLASS_INITIALIZED)) {
286 log_message_class("Initialize class ", m->clazz);
289 if (!initialize_class(m->clazz))
292 /* check if the method has been compiled during initialization */
294 if ((m->code != NULL) && (m->code->entrypoint != NULL))
295 return m->code->entrypoint;
298 /* enter a monitor on the method */
300 LOCK_MONITOR_ENTER(m);
302 /* if method has been already compiled return immediately */
304 if (m->code != NULL) {
305 LOCK_MONITOR_EXIT(m);
307 assert(m->code->entrypoint);
308 return m->code->entrypoint;
311 TRACECOMPILERCALLS();
313 STATISTICS(count_methods++);
315 #if defined(ENABLE_STATISTICS)
318 if (opt_getcompilingtime)
319 compilingtime_start();
322 /* mark start of dump memory area */
326 /* create jitdata structure */
328 jd = jit_jitdata_new(m);
330 /* set the flags for the current JIT run */
332 jd->flags = JITDATA_FLAG_PARSE;
334 #if defined(ENABLE_VERIFIER)
336 jd->flags |= JITDATA_FLAG_VERIFY;
339 #if defined(ENABLE_PROFILING)
341 jd->flags |= JITDATA_FLAG_INSTRUMENT;
344 #if defined(ENABLE_IFCONV)
346 jd->flags |= JITDATA_FLAG_IFCONV;
349 #if defined(ENABLE_INLINING) && defined(ENABLE_INLINING_DEBUG)
350 if (opt_Inline && opt_InlineAll)
351 jd->flags |= JITDATA_FLAG_INLINE;
354 if (opt_showintermediate)
355 jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
357 if (opt_showdisassemble)
358 jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
361 jd->flags |= JITDATA_FLAG_VERBOSECALL;
363 #if defined(ENABLE_REPLACEMENT) && defined(ENABLE_INLINING)
364 if (opt_Inline && (jd->m->hitcountdown > 0) && (jd->code->optlevel == 0)) {
365 jd->flags |= JITDATA_FLAG_COUNTDOWN;
369 #if defined(ENABLE_JIT)
370 # if defined(ENABLE_INTRP)
373 /* initialize the register allocator */
379 /* setup the codegendata memory */
383 /* now call internal compile function */
385 r = jit_compile_intern(jd);
388 /* We had an exception! Finish stuff here if necessary. */
390 /* release codeinfo */
392 code_codeinfo_free(jd->code);
394 #if defined(ENABLE_PROFILING)
395 /* Release memory for basic block profiling information. */
397 if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
398 if (jd->code->bbfrequency != NULL)
399 MFREE(jd->code->bbfrequency, u4, jd->code->basicblockcount);
403 DEBUG_JIT_COMPILEVERBOSE("Running: ");
406 /* release dump area */
410 #if defined(ENABLE_STATISTICS)
413 if (opt_getcompilingtime)
414 compilingtime_stop();
417 #if defined(ENABLE_OPAGENT)
418 if (opt_EnableOpagent)
419 OprofileAgent_newmethod(m);
422 /* leave the monitor */
424 LOCK_MONITOR_EXIT(m);
426 /* return pointer to the methods entry point */
432 /* jit_recompile ***************************************************************
434 Recompiles a Java method.
436 *******************************************************************************/
438 u1 *jit_recompile(methodinfo *m)
445 /* check for max. optimization level */
447 optlevel = (m->code) ? m->code->optlevel : 0;
451 /* log_message_method("not recompiling: ", m); */
456 DEBUG_JIT_COMPILEVERBOSE("Recompiling start: ");
458 STATISTICS(count_jit_calls++);
460 #if defined(ENABLE_STATISTICS)
463 if (opt_getcompilingtime)
464 compilingtime_start();
467 /* mark start of dump memory area */
471 /* create jitdata structure */
473 jd = jit_jitdata_new(m);
475 /* set the current optimization level to the previous one plus 1 */
477 jd->code->optlevel = optlevel + 1;
479 /* get the optimization flags for the current JIT run */
481 #if defined(ENABLE_VERIFIER)
482 jd->flags |= JITDATA_FLAG_VERIFY;
485 /* jd->flags |= JITDATA_FLAG_REORDER; */
486 if (opt_showintermediate)
487 jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
488 if (opt_showdisassemble)
489 jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
491 jd->flags |= JITDATA_FLAG_VERBOSECALL;
493 #if defined(ENABLE_INLINING)
495 jd->flags |= JITDATA_FLAG_INLINE;
498 #if defined(ENABLE_JIT)
499 # if defined(ENABLE_INTRP)
502 /* initialize the register allocator */
507 /* setup the codegendata memory */
511 /* now call internal compile function */
513 r = jit_compile_intern(jd);
516 /* We had an exception! Finish stuff here if necessary. */
518 /* release codeinfo */
520 code_codeinfo_free(jd->code);
523 /* release dump area */
527 #if defined(ENABLE_STATISTICS)
530 if (opt_getcompilingtime)
531 compilingtime_stop();
534 #if defined(ENABLE_OPAGENT)
535 if (opt_EnableOpagent)
536 OprofileAgent_newmethod(m);
539 DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
541 /* return pointer to the methods entry point */
546 #if defined(ENABLE_PM_HACKS)
547 #include "vm/jit/jit_pm_1.inc"
550 /* jit_compile_intern **********************************************************
552 Static internal function which does the actual compilation.
554 *******************************************************************************/
556 static u1 *jit_compile_intern(jitdata *jd)
562 #if defined(ENABLE_RT_TIMING)
563 struct timespec time_start,time_checks,time_parse,time_stack,
564 time_typecheck,time_loop,time_ifconv,time_alloc,
568 RT_TIMING_GET_TIME(time_start);
570 /* get required compiler data */
572 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
579 #if defined(ENABLE_DEBUG_FILTER)
580 show_filters_apply(jd->m);
583 /* Handle native methods and create a native stub. */
585 if (m->flags & ACC_NATIVE) {
588 f = native_method_resolve(m);
593 code = codegen_generate_stub_native(m, f);
595 /* Native methods are never recompiled. */
601 return code->entrypoint;
604 /* if there is no javacode, print error message and return empty method */
606 if (m->jcode == NULL) {
607 DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
609 code->entrypoint = (u1 *) (ptrint) do_nothing_function;
612 return code->entrypoint; /* return empty method */
615 #if defined(ENABLE_STATISTICS)
617 count_javacodesize += m->jcodelength + 18;
618 count_tryblocks += jd->exceptiontablelength;
619 count_javaexcsize += jd->exceptiontablelength * SIZEOF_VOID_P;
623 RT_TIMING_GET_TIME(time_checks);
625 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
626 /* Code for Sun's OpenJDK (see
627 hotspot/src/share/vm/classfile/verifier.cpp
628 (Verifier::is_eligible_for_verification)): Don't verify
629 dynamically-generated bytecodes. */
631 # if defined(ENABLE_VERIFIER)
632 if (class_issubclass(m->clazz, class_sun_reflect_MagicAccessorImpl))
633 jd->flags &= ~JITDATA_FLAG_VERIFY;
637 /* call the compiler passes ***********************************************/
639 DEBUG_JIT_COMPILEVERBOSE("Parsing: ");
641 /* call parse pass */
644 DEBUG_JIT_COMPILEVERBOSE("Exception while parsing: ");
648 RT_TIMING_GET_TIME(time_parse);
650 DEBUG_JIT_COMPILEVERBOSE("Parsing done: ");
652 #if defined(ENABLE_JIT)
653 # if defined(ENABLE_INTRP)
656 DEBUG_JIT_COMPILEVERBOSE("Analysing: ");
658 /* call stack analysis pass */
660 if (!stack_analyse(jd)) {
661 DEBUG_JIT_COMPILEVERBOSE("Exception while analysing: ");
665 RT_TIMING_GET_TIME(time_stack);
667 DEBUG_JIT_COMPILEVERBOSE("Analysing done: ");
669 #ifdef ENABLE_VERIFIER
670 if (JITDATA_HAS_FLAG_VERIFY(jd)) {
671 DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
673 /* call typecheck pass */
674 if (!typecheck(jd)) {
675 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking: ");
680 DEBUG_JIT_COMPILEVERBOSE("Typechecking done: ");
683 RT_TIMING_GET_TIME(time_typecheck);
685 #if defined(ENABLE_LOOP)
690 jit_renumber_basicblocks(jd);
693 RT_TIMING_GET_TIME(time_loop);
695 #if defined(ENABLE_IFCONV)
696 if (JITDATA_HAS_FLAG_IFCONV(jd)) {
697 if (!ifconv_static(jd))
699 jit_renumber_basicblocks(jd);
702 RT_TIMING_GET_TIME(time_ifconv);
706 #if defined(ENABLE_INLINING) && (!defined(ENABLE_ESCAPE) || 1)
707 if (JITDATA_HAS_FLAG_INLINE(jd)) {
708 if (!inline_inline(jd))
713 #if defined(ENABLE_SSA)
715 fix_exception_handlers(jd);
719 /* Build the CFG. This has to be done after stack_analyse, as
720 there happens the JSR elimination. */
725 #if defined(ENABLE_PROFILING)
726 /* Basic block reordering. I think this should be done after
727 if-conversion, as we could lose the ability to do the
730 if (JITDATA_HAS_FLAG_REORDER(jd)) {
733 jit_renumber_basicblocks(jd);
737 #if defined(ENABLE_PM_HACKS)
738 #include "vm/jit/jit_pm_2.inc"
740 DEBUG_JIT_COMPILEVERBOSE("Allocating registers: ");
742 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
743 /* allocate registers */
748 STATISTICS(count_methods_allocated_by_lsra++);
751 # endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
752 #if defined(ENABLE_SSA)
753 /* allocate registers */
756 jd->code->optlevel > 0)
757 /* strncmp(jd->m->name->text, "hottie", 6) == 0*/
758 /*&& jd->exceptiontablelength == 0*/
760 /*printf("=== %s ===\n", jd->m->name->text);*/
761 jd->ls = DNEW(lsradata);
764 /*lsra(jd);*/ regalloc(jd);
765 /*eliminate_subbasicblocks(jd);*/
766 STATISTICS(count_methods_allocated_by_lsra++);
769 # endif /* defined(ENABLE_SSA) */
771 STATISTICS(count_locals_conflicts += (jd->maxlocals - 1) * (jd->maxlocals));
776 STATISTICS(simplereg_make_statistics(jd));
778 DEBUG_JIT_COMPILEVERBOSE("Allocating registers done: ");
779 # if defined(ENABLE_INTRP)
782 #endif /* defined(ENABLE_JIT) */
783 RT_TIMING_GET_TIME(time_alloc);
785 #if defined(ENABLE_PROFILING)
786 /* Allocate memory for basic block profiling information. This
787 _must_ be done after loop optimization and register allocation,
788 since they can change the basic block count. */
790 if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
791 code->bbfrequency = MNEW(u4, jd->basicblockcount);
794 DEBUG_JIT_COMPILEVERBOSE("Generating code: ");
796 /* now generate the machine code */
798 #if defined(ENABLE_JIT)
799 # if defined(ENABLE_INTRP)
801 #if defined(ENABLE_VERIFIER)
803 DEBUG_JIT_COMPILEVERBOSE("Typechecking (stackbased): ");
805 if (!typecheck_stackbased(jd)) {
806 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking (stackbased): ");
811 if (!intrp_codegen(jd)) {
812 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
819 if (!codegen_generate(jd)) {
820 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
826 if (!intrp_codegen(jd)) {
827 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
832 RT_TIMING_GET_TIME(time_codegen);
834 DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
836 #if !defined(NDEBUG) && defined(ENABLE_REPLACEMENT)
837 /* activate replacement points inside newly created code */
839 if (opt_TestReplacement)
840 replace_activate_replacement_points(code, false);
844 #if defined(ENABLE_DEBUG_FILTER)
845 if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
848 /* intermediate and assembly code listings */
850 if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
851 show_method(jd, SHOW_CODE);
853 else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
854 # if defined(ENABLE_DISASSEMBLER)
855 DISASSEMBLE(code->entrypoint,
856 code->entrypoint + (code->mcodelength - cd->dseglen));
860 if (opt_showddatasegment)
865 /* switch to the newly generated code */
868 assert(code->entrypoint);
870 /* add the current compile version to the methodinfo */
872 code->prev = m->code;
875 RT_TIMING_TIME_DIFF(time_start,time_checks,RT_TIMING_JIT_CHECKS);
876 RT_TIMING_TIME_DIFF(time_checks,time_parse,RT_TIMING_JIT_PARSE);
877 RT_TIMING_TIME_DIFF(time_parse,time_stack,RT_TIMING_JIT_STACK);
878 RT_TIMING_TIME_DIFF(time_stack,time_typecheck,RT_TIMING_JIT_TYPECHECK);
879 RT_TIMING_TIME_DIFF(time_typecheck,time_loop,RT_TIMING_JIT_LOOP);
880 RT_TIMING_TIME_DIFF(time_loop,time_alloc,RT_TIMING_JIT_ALLOC);
881 RT_TIMING_TIME_DIFF(time_alloc,time_codegen,RT_TIMING_JIT_CODEGEN);
882 RT_TIMING_TIME_DIFF(time_start,time_codegen,RT_TIMING_JIT_TOTAL);
884 /* return pointer to the methods entry point */
886 return code->entrypoint;
890 /* jit_invalidate_code *********************************************************
892 Mark the compiled code of the given method as invalid and take care that
893 it is replaced if necessary.
895 XXX Not fully implemented, yet.
897 *******************************************************************************/
899 void jit_invalidate_code(methodinfo *m)
905 if (code == NULL || code_is_invalid(code))
908 code_flag_invalid(code);
910 /* activate mappable replacement points */
912 #if defined(ENABLE_REPLACEMENT)
913 replace_activate_replacement_points(code, true);
915 vm_abort("invalidating code only works with ENABLE_REPLACEMENT");
920 /* jit_request_optimization ****************************************************
922 Request optimization of the given method. If the code of the method is
923 unoptimized, it will be invalidated, so the next jit_get_current_code(m)
924 triggers an optimized recompilation.
925 If the method is already optimized, this function does nothing.
928 m................the method
930 *******************************************************************************/
932 void jit_request_optimization(methodinfo *m)
938 if (code && code->optlevel == 0)
939 jit_invalidate_code(m);
943 /* jit_get_current_code ********************************************************
945 Get the currently valid code for the given method. If there is no valid
946 code, (re)compile the method.
949 m................the method
952 the codeinfo* for the current code, or
953 NULL if an exception has been thrown during recompilation.
955 *******************************************************************************/
957 codeinfo *jit_get_current_code(methodinfo *m)
961 /* if we have valid code, return it */
963 if (m->code && !code_is_invalid(m->code))
966 /* otherwise: recompile */
968 if (!jit_recompile(m))
977 /* jit_asm_compile *************************************************************
979 This method is called from asm_vm_call_method and does:
981 - create stackframe info for exceptions
983 - patch the entrypoint of the method into the calculated address in
985 - flushes the instruction cache.
987 *******************************************************************************/
989 #if defined(ENABLE_JIT)
990 #if !defined(JIT_COMPILER_VIA_SIGNAL)
991 u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
993 stackframeinfo_t sfi;
998 /* create the stackframeinfo (subtract 1 from RA as it points to the */
999 /* instruction after the call) */
1001 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra-1);
1003 /* actually compile the method */
1005 entrypoint = jit_compile(m);
1007 /* remove the stackframeinfo */
1009 stacktrace_stackframeinfo_remove(&sfi);
1011 /* there was a problem during compilation */
1013 if (entrypoint == NULL)
1016 /* get the method patch address */
1018 pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
1020 /* patch the method entry point */
1024 *p = (ptrint) entrypoint;
1026 /* flush the instruction cache */
1028 md_icacheflush(pa, SIZEOF_VOID_P);
1034 /* jit_compile_handle **********************************************************
1036 This method is called from the appropriate signal handler which
1037 handles compiler-traps and does the following:
1039 - compile the method
1040 - patch the entrypoint of the method into the calculated address in
1042 - flush the instruction cache
1044 *******************************************************************************/
1046 void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
1048 void *newpv; /* new compiled method PV */
1049 void *pa; /* patch address */
1050 uintptr_t *p; /* convenience pointer */
1052 /* Compile the method. */
1054 newpv = jit_compile(m);
1056 /* There was a problem during compilation. */
1061 /* Get the method patch address. */
1063 pa = md_jit_method_patch_address(pv, ra, mptr);
1065 /* Patch the method entry point. */
1067 p = (uintptr_t *) pa;
1069 *p = (uintptr_t) newpv;
1071 /* Flush both caches. */
1073 md_cacheflush(pa, SIZEOF_VOID_P);
1077 #endif /* defined(ENABLE_JIT) */
1080 /* jit_complement_condition ****************************************************
1082 Returns the complement of the passed conditional instruction.
1084 We use the order of the different conditions, e.g.:
1089 If the passed opcode is odd, we simply add 1 to get the complement.
1090 If the opcode is even, we subtract 1.
1097 *******************************************************************************/
1099 s4 jit_complement_condition(s4 opcode)
1103 return ICMD_IFNONNULL;
1105 case ICMD_IFNONNULL:
1109 /* check if opcode is odd */
1119 /* jit_renumber_basicblocks ****************************************************
1121 Set the ->nr of all blocks so it increases when traversing ->next.
1124 jitdata..........the current jitdata
1126 *******************************************************************************/
1128 void jit_renumber_basicblocks(jitdata *jd)
1134 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1138 /* we have one block more than jd->basicblockcount (the end marker) */
1140 assert(nr == jd->basicblockcount + 1);
1144 /* jit_check_basicblock_numbers ************************************************
1146 Assert that the ->nr of the first block is zero and increases by 1 each
1147 time ->next is traversed.
1148 This function should be called before any analysis that relies on
1149 the basicblock numbers.
1152 jitdata..........the current jitdata
1154 NOTE: Aborts with an assertion if the condition is not met!
1156 *******************************************************************************/
1158 #if !defined(NDEBUG)
1159 void jit_check_basicblock_numbers(jitdata *jd)
1165 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1166 assert(bptr->nr == nr);
1170 /* we have one block more than jd->basicblockcount (the end marker) */
1172 assert(nr == jd->basicblockcount + 1);
1174 #endif /* !defined(NDEBUG) */
1178 * These are local overrides for various environment variables in Emacs.
1179 * Please do not remove this and leave it at the end of the file, where
1180 * Emacs will automagically detect them.
1181 * ---------------------------------------------------------------------
1184 * indent-tabs-mode: t
1188 * vim:noexpandtab:sw=4:ts=4: