1 /* src/vm/jit/codegen-common.cpp - architecture independent code generator stuff
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
23 All functions assume the following code area / data area layout:
27 | code area | code area grows to higher addresses
29 +-----------+ <-- start of procedure
31 | data area | data area grows to lower addresses
35 The functions first write into a temporary code/data area allocated by
36 "codegen_init". "codegen_finish" copies the code and data area into permanent
37 memory. All functions writing values into the data area return the offset
38 relative the begin of the code area (start of procedure).
48 #include "vm/jit/jitcache.hpp"
56 #include "mm/memory.h"
58 #include "toolbox/avl.h"
59 #include "toolbox/list.hpp"
60 #include "toolbox/logging.h"
62 #include "native/llni.h"
63 #include "native/localref.hpp"
64 #include "native/native.hpp"
66 #include "threads/thread.hpp"
68 #include "vm/jit/builtin.hpp"
69 #include "vm/exceptions.hpp"
70 #include "vm/method.h"
71 #include "vm/options.h"
72 #include "vm/string.hpp"
74 # include "vm/statistics.h"
77 #include "vm/jit/abi.h"
78 #include "vm/jit/asmpart.h"
79 #include "vm/jit/code.hpp"
80 #include "vm/jit/codegen-common.hpp"
82 #if defined(ENABLE_DISASSEMBLER)
83 # include "vm/jit/disass.h"
86 #include "vm/jit/dseg.h"
87 #include "vm/jit/emit-common.hpp"
88 #include "vm/jit/jit.hpp"
89 #include "vm/jit/linenumbertable.hpp"
90 #include "vm/jit/methodheader.h"
91 #include "vm/jit/methodtree.h"
92 #include "vm/jit/patcher-common.hpp"
93 #include "vm/jit/replace.hpp"
94 #if defined(ENABLE_SSA)
95 # include "vm/jit/optimizing/lsra.h"
96 # include "vm/jit/optimizing/ssa.h"
98 #include "vm/jit/stacktrace.hpp"
99 #include "vm/jit/trace.hpp"
101 #if defined(ENABLE_INTRP)
102 #include "vm/jit/intrp/intrp.h"
105 #if defined(ENABLE_VMLOG)
106 #include <vmlog_cacao.h>
112 /* codegen_init ****************************************************************
116 *******************************************************************************/
118 void codegen_init(void)
123 /* codegen_setup ***************************************************************
125 Allocates and initialises code area, data area and references.
127 *******************************************************************************/
129 void codegen_setup(jitdata *jd)
134 /* get required compiler data */
139 /* initialize members */
143 cd->mcodebase = (u1*) DumpMemory::allocate(MCODEINITSIZE);
144 cd->mcodeend = cd->mcodebase + MCODEINITSIZE;
145 cd->mcodesize = MCODEINITSIZE;
147 /* initialize mcode variables */
149 cd->mcodeptr = cd->mcodebase;
150 cd->lastmcodeptr = cd->mcodebase;
152 #if defined(ENABLE_INTRP)
153 /* native dynamic superinstructions variables */
156 cd->ncodebase = (u1*) DumpMemory::allocate(NCODEINITSIZE);
157 cd->ncodesize = NCODEINITSIZE;
159 /* initialize ncode variables */
161 cd->ncodeptr = cd->ncodebase;
163 cd->lastinstwithoutdispatch = ~0; /* no inst without dispatch */
164 cd->superstarts = NULL;
171 cd->jumpreferences = NULL;
173 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
174 cd->datareferences = NULL;
177 cd->brancheslabel = new DumpList<branch_label_ref_t*>();
178 cd->linenumbers = new DumpList<Linenumber>();
182 /* codegen_reset ***************************************************************
184 Resets the codegen data structure so we can recompile the method.
186 *******************************************************************************/
188 static void codegen_reset(jitdata *jd)
194 /* get required compiler data */
199 /* reset error flag */
201 cd->flags &= ~CODEGENDATA_FLAG_ERROR;
203 /* reset some members, we reuse the code memory already allocated
204 as this should have almost the correct size */
206 cd->mcodeptr = cd->mcodebase;
207 cd->lastmcodeptr = cd->mcodebase;
212 cd->jumpreferences = NULL;
214 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
215 cd->datareferences = NULL;
218 cd->brancheslabel = new DumpList<branch_label_ref_t*>();
219 cd->linenumbers = new DumpList<Linenumber>();
221 /* We need to clear the mpc and the branch references from all
222 basic blocks as they will definitely change. */
224 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
226 bptr->branchrefs = NULL;
229 /* We need to clear all the patcher references from the codeinfo
230 since they all will be regenerated */
232 patcher_list_reset(code);
234 #if defined(ENABLE_REPLACEMENT)
235 code->rplpoints = NULL;
236 code->rplpointcount = 0;
237 code->regalloc = NULL;
238 code->regalloccount = 0;
239 code->globalcount = 0;
244 /* codegen_generate ************************************************************
246 Generates the code for the currently compiled method.
248 *******************************************************************************/
250 bool codegen_generate(jitdata *jd)
254 /* get required compiler data */
258 /* call the machine-dependent code generation function */
260 if (!codegen_emit(jd))
263 /* check for an error */
265 if (CODEGENDATA_HAS_FLAG_ERROR(cd)) {
266 /* check for long-branches flag, if it is set we recompile the
271 log_message_method("Re-generating code: ", jd->m);
274 /* XXX maybe we should tag long-branches-methods for recompilation */
276 if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
277 /* we have to reset the codegendata structure first */
281 /* and restart the compiler run */
283 if (!codegen_emit(jd))
287 vm_abort("codegen_generate: unknown error occurred during codegen_emit: flags=%x\n", cd->flags);
292 log_message_method("Re-generating code done: ", jd->m);
296 /* reallocate the memory and finish the code generation */
300 /* everything's ok */
306 /* codegen_close ***************************************************************
310 *******************************************************************************/
312 void codegen_close(void)
314 /* TODO: release avl tree on i386 and x86_64 */
318 /* codegen_increase ************************************************************
322 *******************************************************************************/
324 void codegen_increase(codegendata *cd)
328 /* save old mcodebase pointer */
330 oldmcodebase = cd->mcodebase;
332 /* reallocate to new, doubled memory */
334 cd->mcodebase = (u1*) DumpMemory::reallocate(cd->mcodebase,
338 cd->mcodeend = cd->mcodebase + cd->mcodesize;
340 /* set new mcodeptr */
342 cd->mcodeptr = cd->mcodebase + (cd->mcodeptr - oldmcodebase);
344 #if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__) || defined(ENABLE_INTRP) \
345 || defined(__SPARC_64__)
346 /* adjust the pointer to the last patcher position */
348 if (cd->lastmcodeptr != NULL)
349 cd->lastmcodeptr = cd->mcodebase + (cd->lastmcodeptr - oldmcodebase);
354 /* codegen_ncode_increase ******************************************************
358 *******************************************************************************/
360 #if defined(ENABLE_INTRP)
361 u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr)
365 /* save old ncodebase pointer */
367 oldncodebase = cd->ncodebase;
369 /* reallocate to new, doubled memory */
371 cd->ncodebase = DMREALLOC(cd->ncodebase,
377 /* return the new ncodeptr */
379 return (cd->ncodebase + (ncodeptr - oldncodebase));
384 /* codegen_add_branch_ref ******************************************************
386 Prepends an branch to the list.
388 *******************************************************************************/
390 void codegen_add_branch_ref(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
395 STATISTICS(count_branches_unresolved++);
397 /* calculate the mpc of the branch instruction */
399 branchmpc = cd->mcodeptr - cd->mcodebase;
401 br = (branchref*) DumpMemory::allocate(sizeof(branchref));
403 br->branchmpc = branchmpc;
404 br->condition = condition;
406 br->options = options;
407 br->next = target->branchrefs;
409 target->branchrefs = br;
413 /* codegen_resolve_branchrefs **************************************************
415 Resolves and patches the branch references of a given basic block.
417 *******************************************************************************/
419 void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr)
424 /* Save the mcodeptr because in the branch emitting functions
425 we generate code somewhere inside already generated code,
426 but we're still in the actual code generation phase. */
428 mcodeptr = cd->mcodeptr;
430 /* just to make sure */
432 assert(bptr->mpc >= 0);
434 for (br = bptr->branchrefs; br != NULL; br = br->next) {
435 /* temporary set the mcodeptr */
437 cd->mcodeptr = cd->mcodebase + br->branchmpc;
439 /* emit_bccz and emit_branch emit the correct code, even if we
440 pass condition == BRANCH_UNCONDITIONAL or reg == -1. */
442 emit_bccz(cd, bptr, br->condition, br->reg, br->options);
445 /* restore mcodeptr */
447 cd->mcodeptr = mcodeptr;
451 /* codegen_branch_label_add ****************************************************
453 Append an branch to the label-branch list.
455 *******************************************************************************/
457 void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
459 // Calculate the current mpc.
460 int32_t mpc = cd->mcodeptr - cd->mcodebase;
462 branch_label_ref_t* br = (branch_label_ref_t*) DumpMemory::allocate(sizeof(branch_label_ref_t));
466 br->condition = condition;
468 br->options = options;
470 // Add the branch to the list.
471 cd->brancheslabel->push_back(br);
475 /* codegen_set_replacement_point_notrap ****************************************
477 Record the position of a non-trappable replacement point.
479 *******************************************************************************/
481 #if defined(ENABLE_REPLACEMENT)
483 void codegen_set_replacement_point_notrap(codegendata *cd, s4 type)
485 void codegen_set_replacement_point_notrap(codegendata *cd)
488 assert(cd->replacementpoint);
489 assert(cd->replacementpoint->type == type);
490 assert(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP);
492 cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
494 cd->replacementpoint++;
496 #endif /* defined(ENABLE_REPLACEMENT) */
499 /* codegen_set_replacement_point ***********************************************
501 Record the position of a trappable replacement point.
503 *******************************************************************************/
505 #if defined(ENABLE_REPLACEMENT)
507 void codegen_set_replacement_point(codegendata *cd, s4 type)
509 void codegen_set_replacement_point(codegendata *cd)
512 assert(cd->replacementpoint);
513 assert(cd->replacementpoint->type == type);
514 assert(!(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP));
516 cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
518 cd->replacementpoint++;
521 /* XXX actually we should use an own REPLACEMENT_NOPS here! */
522 if (opt_TestReplacement)
526 /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */
528 cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
530 #endif /* defined(ENABLE_REPLACEMENT) */
533 /* codegen_finish **************************************************************
535 Finishes the code generation. A new memory, large enough for both
536 data and code, is allocated and data and code are copied together
537 to their final layout, unresolved jumps are resolved, ...
539 *******************************************************************************/
541 void codegen_finish(jitdata *jd)
546 #if defined(ENABLE_INTRP)
554 /* get required compiler data */
559 /* prevent compiler warning */
561 #if defined(ENABLE_INTRP)
565 /* calculate the code length */
567 mcodelen = (s4) (cd->mcodeptr - cd->mcodebase);
569 #if defined(ENABLE_STATISTICS)
571 count_code_len += mcodelen;
572 count_data_len += cd->dseglen;
576 alignedmcodelen = MEMORY_ALIGN(mcodelen, MAX_ALIGN);
578 #if defined(ENABLE_INTRP)
580 ncodelen = cd->ncodeptr - cd->ncodebase;
582 ncodelen = 0; /* avoid compiler warning */
586 cd->dseglen = MEMORY_ALIGN(cd->dseglen, MAX_ALIGN);
587 alignedlen = alignedmcodelen + cd->dseglen;
589 #if defined(ENABLE_INTRP)
591 alignedlen += ncodelen;
595 /* allocate new memory */
597 code->mcodelength = mcodelen + cd->dseglen;
598 code->mcode = CNEW(u1, alignedlen);
600 /* set the entrypoint of the method */
602 assert(code->entrypoint == NULL);
603 code->entrypoint = epoint = (code->mcode + cd->dseglen);
605 /* fill the data segment (code->entrypoint must already be set!) */
609 /* copy code to the new location */
611 MCOPY((void *) code->entrypoint, cd->mcodebase, u1, mcodelen);
613 #if defined(ENABLE_INTRP)
614 /* relocate native dynamic superinstruction code (if any) */
617 cd->mcodebase = code->entrypoint;
620 u1 *ncodebase = code->mcode + cd->dseglen + alignedmcodelen;
622 MCOPY((void *) ncodebase, cd->ncodebase, u1, ncodelen);
624 /* flush the instruction and data caches */
626 md_cacheflush(ncodebase, ncodelen);
628 /* set some cd variables for dynamic_super_rerwite */
630 cd->ncodebase = ncodebase;
633 cd->ncodebase = NULL;
636 dynamic_super_rewrite(cd);
640 /* Create the exception table. */
642 exceptiontable_create(jd);
644 /* Create the linenumber table. */
646 code->linenumbertable = new LinenumberTable(jd);
648 /* jump table resolving */
650 for (jr = cd->jumpreferences; jr != NULL; jr = jr->next)
652 *((functionptr *) ((ptrint) epoint + jr->tablepos)) =
653 (functionptr) ((ptrint) epoint + (ptrint) jr->target->mpc);
655 JITCACHE_ADD_CACHED_REF(code, CRT_JUMPREFERENCE, jr->target->mpc, jr->tablepos);
658 /* patcher resolving */
662 #if defined(ENABLE_REPLACEMENT)
663 /* replacement point resolving */
668 rp = code->rplpoints;
669 for (i=0; i<code->rplpointcount; ++i, ++rp) {
670 rp->pc = (u1*) ((ptrint) epoint + (ptrint) rp->pc);
673 #endif /* defined(ENABLE_REPLACEMENT) */
675 /* Insert method into methodtree to find the entrypoint. */
677 methodtree_insert(code->entrypoint, code->entrypoint + mcodelen);
679 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
680 /* resolve data segment references */
682 dseg_resolve_datareferences(jd);
685 /* flush the instruction and data caches */
687 md_cacheflush(code->mcode, code->mcodelength);
691 /* codegen_start_native_call ***************************************************
693 Prepares the stuff required for a native (JNI) function call:
695 - adds a stackframe info structure to the chain, for stacktraces
696 - prepares the local references table on the stack
698 The layout of the native stub stackframe should look like this:
700 +---------------------------+ <- java SP (of parent Java function)
702 +---------------------------+ <- data SP
704 | stackframe info structure |
706 +---------------------------+
708 | local references table |
710 +---------------------------+
712 | saved registers (if any) |
714 +---------------------------+
716 | arguments (if any) |
718 +---------------------------+ <- current SP (native stub)
720 *******************************************************************************/
722 java_handle_t *codegen_start_native_call(u1 *sp, u1 *pv)
724 stackframeinfo_t *sfi;
734 STATISTICS(count_calls_java_to_native++);
736 /* Get the methodinfo. */
738 m = code_get_methodinfo_for_pv(pv);
742 framesize = *((int32_t *) (pv + FrameSize));
744 assert(framesize >= (int32_t) (sizeof(stackframeinfo_t) + sizeof(localref_table)));
746 /* calculate needed values */
748 #if defined(__ALPHA__) || defined(__ARM__)
749 datasp = sp + framesize - SIZEOF_VOID_P;
750 javasp = sp + framesize;
751 arg_regs = (uint64_t *) sp;
752 arg_stack = (uint64_t *) javasp;
753 #elif defined(__MIPS__)
754 /* MIPS always uses 8 bytes to store the RA */
755 datasp = sp + framesize - 8;
756 javasp = sp + framesize;
757 #elif defined(__S390__)
758 datasp = sp + framesize - 8;
759 javasp = sp + framesize;
760 arg_regs = (uint64_t *) (sp + 96);
761 arg_stack = (uint64_t *) javasp;
762 #elif defined(__I386__) || defined(__M68K__) || defined(__X86_64__)
763 datasp = sp + framesize;
764 javasp = sp + framesize + SIZEOF_VOID_P;
765 arg_regs = (uint64_t *) sp;
766 arg_stack = (uint64_t *) javasp;
767 #elif defined(__POWERPC__)
768 datasp = sp + framesize;
769 javasp = sp + framesize;
770 arg_regs = (uint64_t *) (sp + LA_SIZE + 4 * SIZEOF_VOID_P);
771 arg_stack = (uint64_t *) javasp;
772 #elif defined(__POWERPC64__)
773 datasp = sp + framesize;
774 javasp = sp + framesize;
775 arg_regs = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 4 * SIZEOF_VOID_P);
776 arg_stack = (uint64_t *) javasp;
778 /* XXX is was unable to do this port for SPARC64, sorry. (-michi) */
779 /* XXX maybe we need to pass the RA as argument there */
780 vm_abort("codegen_start_native_call: unsupported architecture");
783 /* get data structures from stack */
785 sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
786 lrt = (localref_table *) (datasp - sizeof(stackframeinfo_t) -
787 sizeof(localref_table));
789 #if defined(ENABLE_JNI)
790 /* add current JNI local references table to this thread */
792 localref_table_add(lrt);
796 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
797 /* print the call-trace if necesarry */
798 /* BEFORE: filling the local reference table */
800 if (opt_TraceJavaCalls)
801 trace_java_call_enter(m, arg_regs, arg_stack);
805 #if defined(ENABLE_HANDLES)
806 /* place all references into the local reference table */
807 /* BEFORE: creating stackframeinfo */
809 localref_native_enter(m, arg_regs, arg_stack);
812 /* Add a stackframeinfo for this native method. We don't have RA
813 and XPC here. These are determined in
814 stacktrace_stackframeinfo_add. */
816 stacktrace_stackframeinfo_add(sfi, pv, sp, NULL, NULL);
818 /* Return a wrapped classinfo for static methods. */
820 if (m->flags & ACC_STATIC)
821 return (java_handle_t *) LLNI_classinfo_wrap(m->clazz);
827 /* codegen_finish_native_call **************************************************
829 Removes the stuff required for a native (JNI) function call.
830 Additionally it checks for an exceptions and in case, get the
831 exception object and clear the pointer.
833 *******************************************************************************/
835 java_object_t *codegen_finish_native_call(u1 *sp, u1 *pv)
837 stackframeinfo_t *sfi;
847 /* get information from method header */
849 code = code_get_codeinfo_for_pv(pv);
851 framesize = *((int32_t *) (pv + FrameSize));
855 /* get the methodinfo */
860 /* calculate needed values */
862 #if defined(__ALPHA__) || defined(__ARM__)
863 datasp = sp + framesize - SIZEOF_VOID_P;
864 ret_regs = (uint64_t *) sp;
865 #elif defined(__MIPS__)
866 /* MIPS always uses 8 bytes to store the RA */
867 datasp = sp + framesize - 8;
868 #elif defined(__S390__)
869 datasp = sp + framesize - 8;
870 ret_regs = (uint64_t *) (sp + 96);
871 #elif defined(__I386__)
872 datasp = sp + framesize;
873 ret_regs = (uint64_t *) (sp + 2 * SIZEOF_VOID_P);
874 #elif defined(__M68K__)
875 datasp = sp + framesize;
876 ret_regs = (uint64_t *) (sp + 2 * 8);
877 #elif defined(__X86_64__)
878 datasp = sp + framesize;
879 ret_regs = (uint64_t *) sp;
880 #elif defined(__POWERPC__)
881 datasp = sp + framesize;
882 ret_regs = (uint64_t *) (sp + LA_SIZE + 2 * SIZEOF_VOID_P);
883 #elif defined(__POWERPC64__)
884 datasp = sp + framesize;
885 ret_regs = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 2 * SIZEOF_VOID_P);
887 vm_abort("codegen_finish_native_call: unsupported architecture");
890 /* get data structures from stack */
892 sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
894 /* Remove current stackframeinfo from chain. */
896 stacktrace_stackframeinfo_remove(sfi);
898 #if defined(ENABLE_HANDLES)
899 /* unwrap the return value from the local reference table */
900 /* AFTER: removing the stackframeinfo */
901 /* BEFORE: releasing the local reference table */
903 localref_native_exit(m, ret_regs);
906 /* get and unwrap the exception */
907 /* AFTER: removing the stackframe info */
908 /* BEFORE: releasing the local reference table */
910 e = exceptions_get_and_clear_exception();
913 #if defined(ENABLE_JNI)
914 /* release JNI local references table for this thread */
916 localref_frame_pop_all();
917 localref_table_remove();
921 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
922 /* print the call-trace if necesarry */
923 /* AFTER: unwrapping the return value */
925 if (opt_TraceJavaCalls)
926 trace_java_call_exit(m, ret_regs);
934 /* codegen_reg_of_var **********************************************************
936 This function determines a register, to which the result of an
937 operation should go, when it is ultimatively intended to store the
938 result in pseudoregister v. If v is assigned to an actual
939 register, this register will be returned. Otherwise (when v is
940 spilled) this function returns tempregnum. If not already done,
941 regoff and flags are set in the stack location.
943 *******************************************************************************/
945 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
947 if (!(v->flags & INMEMORY))
954 /* codegen_reg_of_dst **********************************************************
956 This function determines a register, to which the result of an
957 operation should go, when it is ultimatively intended to store the
958 result in iptr->dst.var. If dst.var is assigned to an actual
959 register, this register will be returned. Otherwise (when it is
960 spilled) this function returns tempregnum. If not already done,
961 regoff and flags are set in the stack location.
963 *******************************************************************************/
965 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
967 return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
971 /* codegen_emit_phi_moves ****************************************************
973 Emits phi moves at the end of the basicblock.
975 *******************************************************************************/
977 #if defined(ENABLE_SSA)
978 void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr)
991 /* Moves from phi functions with highest indices have to be */
992 /* inserted first, since this is the order as is used for */
993 /* conflict resolution */
995 for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
996 lt_d = ls->phi_moves[bptr->nr][i][0];
997 lt_s = ls->phi_moves[bptr->nr][i][1];
998 #if defined(SSA_DEBUG_VERBOSE)
1000 printf("BB %3i Move %3i <- %3i ", bptr->nr, lt_d, lt_s);
1002 if (lt_s == UNUSED) {
1003 #if defined(SSA_DEBUG_VERBOSE)
1005 printf(" ... not processed \n");
1010 d = VAR(ls->lifetime[lt_d].v_index);
1011 s = VAR(ls->lifetime[lt_s].v_index);
1014 if (d->type == -1) {
1015 #if defined(SSA_DEBUG_VERBOSE)
1017 printf("...returning - phi lifetimes where joined\n");
1022 if (s->type == -1) {
1023 #if defined(SSA_DEBUG_VERBOSE)
1025 printf("...returning - phi lifetimes where joined\n");
1031 tmp_i.s1.varindex = ls->lifetime[lt_s].v_index;
1032 tmp_i.dst.varindex = ls->lifetime[lt_d].v_index;
1033 emit_copy(jd, &tmp_i);
1035 #if defined(SSA_DEBUG_VERBOSE)
1036 if (compileverbose) {
1037 if (IS_INMEMORY(d->flags) && IS_INMEMORY(s->flags)) {
1039 printf("M%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1041 else if (IS_INMEMORY(s->flags)) {
1043 printf("R%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1045 else if (IS_INMEMORY(d->flags)) {
1047 printf("M%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1051 printf("R%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1055 #endif /* defined(SSA_DEBUG_VERBOSE) */
1058 #endif /* defined(ENABLE_SSA) */
1061 /* REMOVEME When we have exception handling in C. */
1063 void *md_asm_codegen_get_pv_from_pc(void *ra)
1065 return md_codegen_get_pv_from_pc(ra);
1070 * These are local overrides for various environment variables in Emacs.
1071 * Please do not remove this and leave it at the end of the file, where
1072 * Emacs will automagically detect them.
1073 * ---------------------------------------------------------------------
1076 * indent-tabs-mode: t
1080 * vim:noexpandtab:sw=4:ts=4: