⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reg_alloc2.c

📁 unix下调试内存泄露的工具源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*---------------------------------------------------------------*//*---                                                         ---*//*--- This file (host-generic/reg_alloc2.c) is                ---*//*--- Copyright (C) OpenWorks LLP.  All rights reserved.      ---*//*---                                                         ---*//*---------------------------------------------------------------*//*   This file is part of LibVEX, a library for dynamic binary   instrumentation and translation.   Copyright (C) 2004-2005 OpenWorks LLP.  All rights reserved.   This library is made available under a dual licensing scheme.   If you link LibVEX against other code all of which is itself   licensed under the GNU General Public License, version 2 dated June   1991 ("GPL v2"), then you may use LibVEX under the terms of the GPL   v2, as appearing in the file LICENSE.GPL.  If the file LICENSE.GPL   is missing, you can obtain a copy of the GPL v2 from the Free   Software Foundation Inc., 51 Franklin St, Fifth Floor, Boston, MA   02110-1301, USA.   For any other uses of LibVEX, you must first obtain a commercial   license from OpenWorks LLP.  Please contact info@open-works.co.uk   for information about commercial licensing.   This software is provided by OpenWorks LLP "as is" and any express   or implied warranties, including, but not limited to, the implied   warranties of merchantability and fitness for a particular purpose   are disclaimed.  In no event shall OpenWorks LLP be liable for any   direct, indirect, incidental, special, exemplary, or consequential   damages (including, but not limited to, procurement of substitute   goods or services; loss of use, data, or profits; or business   interruption) however caused and on any theory of liability,   whether in contract, strict liability, or tort (including   negligence or otherwise) arising in any way out of the use of this   software, even if advised of the possibility of such damage.   Neither the names of the U.S. Department of Energy nor the   University of California nor the names of its contributors may be   used to endorse or promote products derived from this software   without prior written permission.*/#include "libvex_basictypes.h"#include "libvex.h"#include "main/vex_util.h"#include "host-generic/h_generic_regs.h"/* Set to 1 for lots of debugging output. */#define DEBUG_REGALLOC 0/* TODO 27 Oct 04:   (Critical): Need a way to statically establish the vreg classes,   else we can't allocate spill slots properly.   Better consistency checking from what isMove tells us.   We can possibly do V-V coalescing even when the src is spilled,   providing we can arrange for the dst to have the same spill slot.   Note that state[].hreg is the same as the available real regs.   Check whether rreg preferencing has any beneficial effect.   Remove preferencing fields in VRegInfo, if not used.   Generally rationalise data structures.  *//* Records information on virtual register live ranges.  Computed once   and remains unchanged after that. */typedef   struct {      /* Becomes live for the first time after this insn ... */      Short live_after;      /* Becomes dead for the last time before this insn ... */      Short dead_before;      /* The "home" spill slot, if needed.  Never changes. */      Short spill_offset;      Short spill_size;      /* What kind of register this is. */      HRegClass reg_class;   }   VRegLR;/* Records information on real-register live ranges.  Computed once   and remains unchanged after that. */typedef   struct {      HReg rreg;      /* Becomes live after this insn ... */      Short live_after;      /* Becomes dead before this insn ... */      Short dead_before;   }   RRegLR;/* An array of the following structs (rreg_state) comprises the   running state of the allocator.  It indicates what the current   disposition of each allocatable real register is.  The array gets   updated as the allocator processes instructions. */typedef   struct {      /* FIELDS WHICH DO NOT CHANGE */      /* Which rreg is this for? */      HReg rreg;      /* Is this involved in any HLRs?  (only an optimisation hint) */      Bool has_hlrs;      /* FIELDS WHICH DO CHANGE */      /* What's it's current disposition? */      enum { Free,     /* available for use */             Unavail,  /* in a real-reg live range */             Bound     /* in use (holding value of some vreg) */           }           disp;      /* If RRegBound, what vreg is it bound to? */      HReg vreg;      /* Used when .disp == Bound and we are looking for vregs to         spill. */      Bool is_spill_cand;   }   RRegState;/* The allocator also maintains a redundant array of indexes   (vreg_state) from vreg numbers back to entries in rreg_state.  It   is redundant because iff vreg_state[i] == j then   hregNumber(rreg_state[j].vreg) == i -- that is, the two entries   point at each other.  The purpose of this is to speed up activities   which involve looking for a particular vreg: there is no need to   scan the rreg_state looking for it, just index directly into   vreg_state.  The FAQ "does this vreg already have an associated   rreg" is the main beneficiary.     To indicate, in vreg_state[i], that a given vreg is not currently   associated with any rreg, that entry can be set to INVALID_RREG_NO.   Because the vreg_state entries are signed Shorts, the max number   of vregs that can be handed by regalloc is 32767.*/#define INVALID_RREG_NO ((Short)(-1))#define IS_VALID_VREGNO(_zz) ((_zz) >= 0 && (_zz) < n_vregs)#define IS_VALID_RREGNO(_zz) ((_zz) >= 0 && (_zz) < n_rregs)/* Does this instruction mention a particular reg? */static Bool instrMentionsReg (    void (*getRegUsage) (HRegUsage*, HInstr*),   HInstr* instr,    HReg r ){   Int       i;   HRegUsage reg_usage;   (*getRegUsage)(&reg_usage, instr);   for (i = 0; i < reg_usage.n_used; i++)      if (reg_usage.hreg[i] == r)         return True;   return False;}/* Search forward from some given point in the incoming instruction   sequence.  Point is to select a virtual register to spill, by   finding the vreg which is mentioned as far ahead as possible, in   the hope that this will minimise the number of consequent reloads.   Only do the search for vregs which are Bound in the running state,   and for which the .is_spill_cand field is set.  This allows the   caller to arbitrarily restrict the set of spill candidates to be   considered.   Returns an index into the state array indicating the (v,r) pair to   spill, or -1 if none was found.  */staticInt findMostDistantlyMentionedVReg (    void (*getRegUsage) (HRegUsage*, HInstr*),   HInstrArray* instrs_in,   Int          search_from_instr,   RRegState*   state,   Int          n_state){   Int k, m;   Int furthest_k = -1;   Int furthest   = -1;   vassert(search_from_instr >= 0);   for (k = 0; k < n_state; k++) {      if (!state[k].is_spill_cand)         continue;      vassert(state[k].disp == Bound);      for (m = search_from_instr; m < instrs_in->arr_used; m++) {         if (instrMentionsReg(getRegUsage,                               instrs_in->arr[m], state[k].vreg))            break;      }      if (m > furthest) {         furthest   = m;         furthest_k = k;      }   }   return furthest_k;}/* Double the size of the real-reg live-range array, if needed. */static void ensureRRLRspace ( RRegLR** info, Int* size, Int used ){   Int     k;   RRegLR* arr2;   if (used < *size) return;   if (0)      vex_printf("ensureRRISpace: %d -> %d\n", *size, 2 * *size);   vassert(used == *size);   arr2 = LibVEX_Alloc(2 * *size * sizeof(RRegLR));   for (k = 0; k < *size; k++)      arr2[k] = (*info)[k];   *size *= 2;   *info = arr2;}/* A target-independent register allocator.  Requires various   functions which it uses to deal abstractly with instructions and   registers, since it cannot have any target-specific knowledge.   Returns a new list of instructions, which, as a result of the   behaviour of mapRegs, will be in-place modifications of the   original instructions.   Requires that the incoming code has been generated using   vreg numbers 0, 1 .. n_vregs-1.  Appearance of a vreg outside   that range is a checked run-time error.   Takes an expandable array of pointers to unallocated insns.   Returns an expandable array of pointers to allocated insns.*/HInstrArray* doRegisterAllocation (   /* Incoming virtual-registerised code. */    HInstrArray* instrs_in,   /* An array listing all the real registers the allocator may use,      in no particular order. */   HReg* available_real_regs,   Int   n_available_real_regs,   /* Return True iff the given insn is a reg-reg move, in which      case also return the src and dst regs. */   Bool (*isMove) (HInstr*, HReg*, HReg*),   /* Get info about register usage in this insn. */   void (*getRegUsage) (HRegUsage*, HInstr*),   /* Apply a reg-reg mapping to an insn. */   void (*mapRegs) (HRegRemap*, HInstr*),   /* Return an insn to spill/restore a real reg to a spill slot      byte offset. */   HInstr* (*genSpill) ( HReg, Int ),   HInstr* (*genReload) ( HReg, Int ),   Int     guest_sizeB,   /* For debug printing only. */   void (*ppInstr) ( HInstr* ),   void (*ppReg) ( HReg )){#  define N_SPILL64S  (LibVEX_N_SPILL_BYTES / 8)   /* Iterators and temporaries. */   Int       ii, j, k, m, spillee, k_suboptimal;   HReg      rreg, vreg, vregS, vregD;   HRegUsage reg_usage;   /* Info on vregs and rregs.  Computed once and remains      unchanged. */   Int     n_vregs;   VRegLR* vreg_lrs; /* [0 .. n_vregs-1] */   RRegLR* rreg_lrs;   Int     rreg_lrs_size;   Int     rreg_lrs_used;   /* Used when constructing vreg_lrs (for allocating stack      slots). */   Int ss_busy_until_before[N_SPILL64S];   /* Used when constructing rreg_lrs. */   Int* rreg_live_after;   Int* rreg_dead_before;   /* Running state of the core allocation algorithm. */   RRegState* rreg_state;  /* [0 .. n_rregs-1] */   Int        n_rregs;   /* .. and the redundant backward map */   /* Each value is 0 .. n_rregs-1 or is INVALID_RREG_NO.      This inplies n_rregs must be <= 32768. */   Short*     vreg_state;  /* [0 .. n_vregs-1] */   /* The vreg -> rreg map constructed and then applied to each      instr. */   HRegRemap remap;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -