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

📄 reg_alloc2.c

📁 unix下调试内存泄露的工具源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
   /* The output array of instructions. */   HInstrArray* instrs_out;   /* Sanity checks are expensive.  They are only done periodically,      not at each insn processed. */   Bool do_sanity_check;   vassert(0 == LibVEX_N_SPILL_BYTES % 16);   vassert(0 == guest_sizeB % 8);   /* The live range numbers are signed shorts, and so limiting the      number of insns to 10000 comfortably guards against them      overflowing 32k. */   vassert(instrs_in->arr_used <= 10000);#  define INVALID_INSTRNO (-2)#  define EMIT_INSTR(_instr)                  \      do {                                    \        HInstr* _tmp = (_instr);              \        if (DEBUG_REGALLOC) {                 \           vex_printf("**  ");                \           (*ppInstr)(_tmp);                  \           vex_printf("\n\n");                \        }                                     \        addHInstr ( instrs_out, _tmp );       \      } while (0)#   define PRINT_STATE						   \      do {							   \         Int z, q;						   \         for (z = 0; z < n_rregs; z++) {			   \            vex_printf("  rreg_state[%2d] = ", z);		   \            (*ppReg)(rreg_state[z].rreg);	       		   \            vex_printf("  \t");					   \            switch (rreg_state[z].disp) {			   \               case Free:    vex_printf("Free\n"); break;	   \               case Unavail: vex_printf("Unavail\n"); break;	   \               case Bound:   vex_printf("BoundTo "); 		   \                             (*ppReg)(rreg_state[z].vreg);	   \                             vex_printf("\n"); break;		   \            }							   \         }							   \         vex_printf("\n  vreg_state[0 .. %d]:\n    ", n_vregs-1);  \         q = 0;                                                    \         for (z = 0; z < n_vregs; z++) {                           \            if (vreg_state[z] == INVALID_RREG_NO)                  \               continue;                                           \            vex_printf("[%d] -> %d   ", z, vreg_state[z]);         \            q++;                                                   \            if (q > 0 && (q % 6) == 0)                             \               vex_printf("\n    ");                               \         }                                                         \         vex_printf("\n");                                         \      } while (0)   /* --------- Stage 0: set up output array --------- */   /* --------- and allocate/initialise running state. --------- */   instrs_out = newHInstrArray();   /* ... and initialise running state. */   /* n_rregs is no more than a short name for n_available_real_regs. */   n_rregs = n_available_real_regs;   n_vregs = instrs_in->n_vregs;   /* If this is not so, vreg_state entries will overflow. */   vassert(n_vregs < 32767);   rreg_state = LibVEX_Alloc(n_rregs * sizeof(RRegState));   vreg_state = LibVEX_Alloc(n_vregs * sizeof(Short));   for (j = 0; j < n_rregs; j++) {      rreg_state[j].rreg          = available_real_regs[j];      rreg_state[j].has_hlrs      = False;      rreg_state[j].disp          = Free;      rreg_state[j].vreg          = INVALID_HREG;      rreg_state[j].is_spill_cand = False;   }   for (j = 0; j < n_vregs; j++)      vreg_state[j] = INVALID_RREG_NO;   /* --------- Stage 1: compute vreg live ranges. --------- */   /* --------- Stage 2: compute rreg live ranges. --------- */   /* ------ start of SET UP TO COMPUTE VREG LIVE RANGES ------ */   /* This is relatively simple, because (1) we only seek the complete      end-to-end live range of each vreg, and are not interested in      any holes in it, and (2) the vregs are conveniently numbered 0      .. n_vregs-1, so we can just dump the results in a      pre-allocated array. */   vreg_lrs = NULL;   if (n_vregs > 0)      vreg_lrs = LibVEX_Alloc(sizeof(VRegLR) * n_vregs);   for (j = 0; j < n_vregs; j++) {      vreg_lrs[j].live_after     = INVALID_INSTRNO;      vreg_lrs[j].dead_before    = INVALID_INSTRNO;      vreg_lrs[j].spill_offset   = 0;      vreg_lrs[j].spill_size     = 0;      vreg_lrs[j].reg_class      = HRcINVALID;   }   /* ------ end of SET UP TO COMPUTE VREG LIVE RANGES ------ */   /* ------ start of SET UP TO COMPUTE RREG LIVE RANGES ------ */   /* This is more complex than Stage 1, because we need to compute      exactly all the live ranges of all the allocatable real regs,      and we don't know in advance how many there will be. */   rreg_lrs_used = 0;   rreg_lrs_size = 4;   rreg_lrs = LibVEX_Alloc(rreg_lrs_size * sizeof(RRegLR));   /* We'll need to track live range start/end points seperately for      each rreg.  Sigh. */   vassert(n_available_real_regs > 0);   rreg_live_after  = LibVEX_Alloc(n_available_real_regs * sizeof(Int));   rreg_dead_before = LibVEX_Alloc(n_available_real_regs * sizeof(Int));   for (j = 0; j < n_available_real_regs; j++) {      rreg_live_after[j] =       rreg_dead_before[j] = INVALID_INSTRNO;   }   /* ------ end of SET UP TO COMPUTE RREG LIVE RANGES ------ */   /* ------ start of ITERATE OVER INSNS ------ */   for (ii = 0; ii < instrs_in->arr_used; ii++) {      (*getRegUsage)( &reg_usage, instrs_in->arr[ii] );#     if 0      vex_printf("\n%d  stage1: ", ii);      (*ppInstr)(instrs_in->arr[ii]);      vex_printf("\n");      ppHRegUsage(&reg_usage);#     endif      /* ------ start of DEAL WITH VREG LIVE RANGES ------ */      /* for each reg mentioned in the insn ... */      for (j = 0; j < reg_usage.n_used; j++) {         vreg = reg_usage.hreg[j];         /* only interested in virtual registers right now. */         if (!hregIsVirtual(vreg))            continue;         k = hregNumber(vreg);         if (k < 0 || k >= n_vregs) {            vex_printf("\n");            (*ppInstr)(instrs_in->arr[ii]);            vex_printf("\n");            vex_printf("vreg %d, n_vregs %d\n", k, n_vregs);            vpanic("doRegisterAllocation: out-of-range vreg");         }         /* Take the opportunity to note its regclass.  We'll need            that when allocating spill slots. */         if (vreg_lrs[k].reg_class == HRcINVALID) {            /* First mention of this vreg. */            vreg_lrs[k].reg_class = hregClass(vreg);         } else {            /* Seen it before, so check for consistency. */            vassert(vreg_lrs[k].reg_class == hregClass(vreg));         }         /* Now consider live ranges. */         switch (reg_usage.mode[j]) {            case HRmRead:                if (vreg_lrs[k].live_after == INVALID_INSTRNO) {                  vex_printf("\n\nOFFENDING VREG = %d\n", k);                  vpanic("doRegisterAllocation: "                         "first event for vreg is Read");               }               vreg_lrs[k].dead_before = toShort(ii + 1);               break;            case HRmWrite:               if (vreg_lrs[k].live_after == INVALID_INSTRNO)                  vreg_lrs[k].live_after = toShort(ii);               vreg_lrs[k].dead_before = toShort(ii + 1);               break;            case HRmModify:               if (vreg_lrs[k].live_after == INVALID_INSTRNO) {                  vex_printf("\n\nOFFENDING VREG = %d\n", k);                  vpanic("doRegisterAllocation: "                         "first event for vreg is Modify");               }               vreg_lrs[k].dead_before = toShort(ii + 1);               break;            default:               vpanic("doRegisterAllocation(1)");         } /* switch */      } /* iterate over registers */      /* ------ end of DEAL WITH VREG LIVE RANGES ------ */      /* ------ start of DEAL WITH RREG LIVE RANGES ------ */      /* for each reg mentioned in the insn ... */      for (j = 0; j < reg_usage.n_used; j++) {         /* Dummy initialisations of flush_la and flush_db to avoid            possible bogus uninit-var warnings from gcc. */         Int  flush_la = INVALID_INSTRNO, flush_db = INVALID_INSTRNO;         Bool flush;         rreg = reg_usage.hreg[j];         /* only interested in real registers right now. */         if (hregIsVirtual(rreg))            continue;         /* Furthermore, we're not interested in this rreg unless it's            one of the allocatable ones.  For example, it could be a            stack pointer register, or some other register beyond our            control, in which case we should just ignore it. */         for (k = 0; k < n_available_real_regs; k++)            if (available_real_regs[k] == rreg)               break;         if (k == n_available_real_regs)             continue; /* not found -- ignore. */         flush = False;         switch (reg_usage.mode[j]) {            case HRmWrite:               flush_la = rreg_live_after[k];               flush_db = rreg_dead_before[k];               if (flush_la != INVALID_INSTRNO                    && flush_db != INVALID_INSTRNO)                  flush = True;               rreg_live_after[k]  = ii;               rreg_dead_before[k] = ii+1;               break;            case HRmRead:               if (rreg_live_after[k] == INVALID_INSTRNO) {                  vex_printf("\nOFFENDING RREG = ");                  (*ppReg)(available_real_regs[k]);                  vex_printf("\n");                  vex_printf("\nOFFENDING instr = ");                  (*ppInstr)(instrs_in->arr[ii]);                  vex_printf("\n");                  vpanic("doRegisterAllocation: "                         "first event for rreg is Read");               }               rreg_dead_before[k] = ii+1;               break;            case HRmModify:               if (rreg_live_after[k] == INVALID_INSTRNO) {                  vex_printf("\nOFFENDING RREG = ");                  (*ppReg)(available_real_regs[k]);                  vex_printf("\n");                  vex_printf("\nOFFENDING instr = ");                  (*ppInstr)(instrs_in->arr[ii]);                  vex_printf("\n");                  vpanic("doRegisterAllocation: "                         "first event for rreg is Modify");               }               rreg_dead_before[k] = ii+1;               break;            default:               vpanic("doRegisterAllocation(2)");         }         if (flush) {            vassert(flush_la != INVALID_INSTRNO);            vassert(flush_db != INVALID_INSTRNO);            ensureRRLRspace(&rreg_lrs, &rreg_lrs_size, rreg_lrs_used);            if (0)                vex_printf("FLUSH 1 (%d,%d)\n", flush_la, flush_db);            rreg_lrs[rreg_lrs_used].rreg        = rreg;            rreg_lrs[rreg_lrs_used].live_after  = toShort(flush_la);            rreg_lrs[rreg_lrs_used].dead_before = toShort(flush_db);            rreg_lrs_used++;         }      } /* iterate over regs in the instr */      /* ------ end of DEAL WITH RREG LIVE RANGES ------ */   } /* iterate over insns */   /* ------ end of ITERATE OVER INSNS ------ */   /* ------ start of FINALISE RREG LIVE RANGES ------ */   /* Now finish up any live ranges left over. */   for (j = 0; j < n_available_real_regs; j++) {#     if 0      vex_printf("residual %d:  %d %d\n", j, rreg_live_after[j],                                             rreg_dead_before[j]);#     endif       vassert( (rreg_live_after[j] == INVALID_INSTRNO                && rreg_dead_before[j] == INVALID_INSTRNO)              ||              (rreg_live_after[j] != INVALID_INSTRNO                && rreg_dead_before[j] != INVALID_INSTRNO)            );      if (rreg_live_after[j] == INVALID_INSTRNO)         continue;      ensureRRLRspace(&rreg_lrs, &rreg_lrs_size, rreg_lrs_used);      if (0)         vex_printf("FLUSH 2 (%d,%d)\n",                     rreg_live_after[j], rreg_dead_before[j]);

⌨️ 快捷键说明

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