From: Julian Seward Date: Wed, 21 Jul 2004 12:28:07 +0000 (+0000) Subject: - Fix up verbosity control. X-Git-Tag: svn/VALGRIND_3_0_1^2~1236 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e0e0f44bd39090d394d85822356a2c98e8eca8f4;p=thirdparty%2Fvalgrind.git - Fix up verbosity control. - A quick bit of profiling and inlining of HReg functions as a result. git-svn-id: svn://svn.valgrind.org/vex/trunk@98 --- diff --git a/VEX/Makefile b/VEX/Makefile index 97fd425243..0ba7165ec9 100644 --- a/VEX/Makefile +++ b/VEX/Makefile @@ -28,7 +28,7 @@ APP_OBJS = test_main.o CC = gcc341 -CCFLAGS = -g -Wall -Wshadow +CCFLAGS = -g -Wall -Wshadow -O #CC = icc #CCFLAGS = -g -Wbrief -Wall -wd981 -wd279 -wd1287 -wd869 \ diff --git a/VEX/priv/guest-x86/x86toIR.c b/VEX/priv/guest-x86/x86toIR.c index 1cd4da11b2..2e87a03a34 100644 --- a/VEX/priv/guest-x86/x86toIR.c +++ b/VEX/priv/guest-x86/x86toIR.c @@ -8,8 +8,10 @@ /* TODO: XOR reg with itself + SBB reg with itself is Iop_Neg* used? - + xadd %reg,%reg fix + MOVAPS fix (vg_to_ucode rev 1.143) */ /* Translates x86 code to IR. */ @@ -7927,9 +7929,11 @@ static UInt disInstr ( UInt delta, Bool* isEnd ) while (True) { if (!first_stmt) break; - vex_printf(" "); - ppIRStmt(first_stmt); - DIP("\n"); + if (print_codegen) { + vex_printf(" "); + ppIRStmt(first_stmt); + vex_printf("\n"); + } if (first_stmt == last_stmt) break; first_stmt = first_stmt->link; diff --git a/VEX/priv/host-generic/host_regs.c b/VEX/priv/host-generic/host_regs.c index 1616ed4d8f..ec4ce5df53 100644 --- a/VEX/priv/host-generic/host_regs.c +++ b/VEX/priv/host-generic/host_regs.c @@ -23,25 +23,6 @@ HReg mkHReg ( UInt regno, HRegClass rc, Bool virtual ) return regno | (((UInt)rc) << 28) | (virtual ? (1<<24) : 0); } -HRegClass hregClass ( HReg r ) -{ - UInt rc = r; - rc = (rc >> 28) & 0x0F; - vassert(rc == HRcInt || rc == HRcFloat || rc == HRcVector - || rc == HRcInt64 || rc == HRcVector128); - return (HRegClass)rc; -} - -Bool hregIsVirtual ( HReg r ) -{ - return (((UInt)r) & (1<<24)) ? True : False; -} - -UInt hregNumber ( HReg r ) -{ - return ((UInt)r) & 0x00FFFFFF; -} - void ppHRegClass ( HRegClass hrc ) { switch (hrc) { diff --git a/VEX/priv/host-generic/host_regs.h b/VEX/priv/host-generic/host_regs.h index c3c9735a65..a3e446f0f3 100644 --- a/VEX/priv/host-generic/host_regs.h +++ b/VEX/priv/host-generic/host_regs.h @@ -65,9 +65,22 @@ extern void ppHReg ( HReg ); /* Construct/destruct. */ extern HReg mkHReg ( UInt regno, HRegClass rc, Bool virtual ); -extern HRegClass hregClass ( HReg ); -extern Bool hregIsVirtual ( HReg ); -extern UInt hregNumber ( HReg ); +static inline HRegClass hregClass ( HReg r ) { + UInt rc = r; + rc = (rc >> 28) & 0x0F; + vassert(rc >= HRcInt || rc <= HRcVector128); + return (HRegClass)rc; +} + +static inline UInt hregNumber ( HReg r ) { + return ((UInt)r) & 0x00FFFFFF; +} + +static inline Bool hregIsVirtual ( HReg r ) { + return (((UInt)r) & (1<<24)) ? True : False; +} + + #define INVALID_HREG ((HReg)0xFFFFFFFF) diff --git a/VEX/priv/host-generic/reg_alloc.c b/VEX/priv/host-generic/reg_alloc.c index 5e95a06b55..15a1d3f1b5 100644 --- a/VEX/priv/host-generic/reg_alloc.c +++ b/VEX/priv/host-generic/reg_alloc.c @@ -143,6 +143,24 @@ Int findMostDistantlyMentionedVReg ( } + +/* Double the size of the real-reg-info array, if needed. */ +static void ensureRRIspace ( RRegInfo** info, Int* size, Int used ) +{ + Int k; + if (used < *size) return; + if (0) + vex_printf("ensureRRISpace: %d -> %d\n", *size, 2 * *size); + vassert(used == *size); + RRegInfo* arr2 + = LibVEX_Alloc(2 * *size * sizeof(RRegInfo)); + for (k = 0; k < *size; k++) + arr2[k] = (*info)[k]; + *size *= 2; + *info = arr2; +} + + /* A target-independent register allocator for Valgrind. Requires various functions which it uses to deal abstractly with instructions and registers, since it cannot have any @@ -408,10 +426,9 @@ HInstrArray* doRegisterAllocation ( if (flush) { vassert(flush_la != INVALID_INSTRNO); vassert(flush_db != INVALID_INSTRNO); - vex_printf("FLUSH 1 (%d,%d)\n", flush_la, flush_db); - if (rreg_info_used == rreg_info_size) { - vpanic("make rreg info array bigger(1)"); - } + ensureRRIspace(&rreg_info, &rreg_info_size, rreg_info_used); + if (0) + vex_printf("FLUSH 1 (%d,%d)\n", flush_la, flush_db); rreg_info[rreg_info_used].rreg = rreg; rreg_info[rreg_info_used].live_after = flush_la; rreg_info[rreg_info_used].dead_before = flush_db; @@ -438,9 +455,11 @@ HInstrArray* doRegisterAllocation ( if (rreg_live_after[j] == INVALID_INSTRNO) continue; - if (rreg_info_used == rreg_info_size) { - vpanic("make rreg info array bigger(2)"); - } + + ensureRRIspace(&rreg_info, &rreg_info_size, rreg_info_used); + if (0) + vex_printf("FLUSH 2 (%d,%d)\n", + rreg_live_after[j], rreg_dead_before[j]); rreg_info[rreg_info_used].rreg = available_real_regs[j]; rreg_info[rreg_info_used].live_after = rreg_live_after[j]; rreg_info[rreg_info_used].dead_before = rreg_dead_before[j]; @@ -569,7 +588,22 @@ HInstrArray* doRegisterAllocation ( && ii < rreg_info[j].dead_before) { /* ii is the middle of a hard live range for some real reg. Check it's marked as such in the running state. */ - vassert(state[rreg_info[j].rreg].disp == Unavail); + +# if 0 + vex_printf("considering la %d .. db %d reg = ", + rreg_info[j].live_after, + rreg_info[j].dead_before); + (*ppReg)(rreg_info[j].rreg); + vex_printf("\n"); +# endif + + /* find the state entry for this rreg */ + for (k = 0; k < n_state; k++) + if (state[k].rreg == rreg_info[j].rreg) + break; + + /* and assert that this rreg is marked as unavailable */ + vassert(state[k].disp == Unavail); } } diff --git a/VEX/priv/host-x86/isel_x86.c b/VEX/priv/host-x86/isel_x86.c index 33d84cf53f..12bde53071 100644 --- a/VEX/priv/host-x86/isel_x86.c +++ b/VEX/priv/host-x86/isel_x86.c @@ -11,6 +11,7 @@ #include "libvex.h" #include "vex_util.h" +#include "vex_globals.h" #include "host_regs.h" #include "x86h_defs.h" @@ -190,8 +191,10 @@ static void lookupIRTemp64 ( HReg* vrHI, HReg* vrLO, ISelEnv* env, IRTemp tmp ) static void addInstr ( ISelEnv* env, X86Instr* instr ) { addHInstr(env->code, instr); - ppX86Instr(instr); - vex_printf("\n"); + if (vex_verbosity > 0) { + ppX86Instr(instr); + vex_printf("\n"); + } } static HReg newVRegI ( ISelEnv* env ) @@ -784,9 +787,11 @@ static void iselIntExpr64 ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) static void iselStmt ( ISelEnv* env, IRStmt* stmt ) { - vex_printf("-- "); - ppIRStmt(stmt); - vex_printf("\n"); + if (vex_verbosity > 0) { + vex_printf("-- "); + ppIRStmt(stmt); + vex_printf("\n"); + } switch (stmt->tag) { @@ -866,7 +871,6 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) case Ist_Exit: { if (stmt->Ist.Exit.dst->tag != Ico_U32) vpanic("isel_x86: Ist_Exit: dst is not a 32-bit value"); - X86RI* dst = iselIntExpr_RI(env, IRExpr_Const(stmt->Ist.Exit.dst)); X86CondCode cc = iselCondCode(env,stmt->Ist.Exit.cond); addInstr(env, X86Instr_Goto(cc, dst)); @@ -887,9 +891,11 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) static void iselNext ( ISelEnv* env, IRExpr* next, IRJumpKind jk ) { X86RI* ri; - vex_printf("-- goto "); - ppIRExpr(next); - vex_printf("\n"); + if (vex_verbosity > 0) { + vex_printf("-- goto "); + ppIRExpr(next); + vex_printf("\n"); + } ri = iselIntExpr_RI(env, next); addInstr(env, X86Instr_Goto(Xcc_ALWAYS,ri)); diff --git a/VEX/priv/host-x86/x86h_defs.c b/VEX/priv/host-x86/x86h_defs.c index dc4fde7bfb..ff75e69c4d 100644 --- a/VEX/priv/host-x86/x86h_defs.c +++ b/VEX/priv/host-x86/x86h_defs.c @@ -620,11 +620,30 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i) addRegUsage_X86RI(u, i->Xin.Alu32M.src); addRegUsage_X86AMode(u, i->Xin.Alu32M.dst); return; + case Xin_Unary32: + addRegUsage_X86RM(u, i->Xin.Unary32.dst, HRmModify); + return; + case Xin_MulL: + addRegUsage_X86RM(u, i->Xin.MulL.src, HRmRead); + addHRegUse(u, HRmModify, hregX86_EAX()); + addHRegUse(u, HRmWrite, hregX86_EDX()); + return; + case Xin_Div: + addRegUsage_X86RM(u, i->Xin.Div.src, HRmRead); + addHRegUse(u, HRmModify, hregX86_EAX()); + addHRegUse(u, HRmModify, hregX86_EDX()); + return; case Xin_Sh32: addRegUsage_X86RM(u, i->Xin.Sh32.dst, HRmModify); if (i->Xin.Sh32.src == 0) addHRegUse(u, HRmRead, hregX86_ECX()); return; + case Xin_Sh3232: + addHRegUse(u, HRmRead, i->Xin.Sh3232.rLo); + addHRegUse(u, HRmModify, i->Xin.Sh3232.rHi); + if (i->Xin.Sh3232.amt == 0) + addHRegUse(u, HRmRead, hregX86_ECX()); + return; case Xin_Push: addRegUsage_X86RMI(u, i->Xin.Push.src); addHRegUse(u, HRmModify, hregX86_ESP()); @@ -641,29 +660,78 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i) addRegUsage_X86RI(u, i->Xin.Goto.dst); addHRegUse(u, HRmWrite, hregX86_EAX()); return; + case Xin_CMov32: + addRegUsage_X86RM(u, i->Xin.CMov32.src, HRmRead); + addHRegUse(u, HRmModify, i->Xin.CMov32.dst); + return; + case Xin_LoadEX: + addRegUsage_X86AMode(u, i->Xin.LoadEX.src); + addHRegUse(u, HRmWrite, i->Xin.LoadEX.dst); + return; + case Xin_Store: + addHRegUse(u, HRmRead, i->Xin.Store.src); + addRegUsage_X86AMode(u, i->Xin.Store.dst); + return; default: ppX86Instr(i); vpanic("getRegUsage_X86Instr"); } } +/* local helper */ +static void mapReg(HRegRemap* m, HReg* r) +{ + *r = lookupHRegRemap(m, *r); +} + void mapRegs_X86Instr (HRegRemap* m, X86Instr* i) { switch (i->tag) { case Xin_Alu32R: mapRegs_X86RMI(m, i->Xin.Alu32R.src); - i->Xin.Alu32R.dst = lookupHRegRemap(m, i->Xin.Alu32R.dst); + mapReg(m, &i->Xin.Alu32R.dst); return; case Xin_Alu32M: mapRegs_X86RI(m, i->Xin.Alu32M.src); mapRegs_X86AMode(m, i->Xin.Alu32M.dst); return; + case Xin_Unary32: + mapRegs_X86RM(m, i->Xin.Unary32.dst); + return; + case Xin_MulL: + mapRegs_X86RM(m, i->Xin.MulL.src); + return; + case Xin_Div: + mapRegs_X86RM(m, i->Xin.Div.src); + return; case Xin_Sh32: mapRegs_X86RM(m, i->Xin.Sh32.dst); return; + case Xin_Sh3232: + mapReg(m, &i->Xin.Sh3232.rLo); + mapReg(m, &i->Xin.Sh3232.rHi); + return; + case Xin_Push: + mapRegs_X86RMI(m, i->Xin.Push.src); + return; + case Xin_Call: + mapReg(m, &i->Xin.Call.target); + return; case Xin_Goto: mapRegs_X86RI(m, i->Xin.Goto.dst); return; + case Xin_CMov32: + mapRegs_X86RM(m, i->Xin.CMov32.src); + mapReg(m, &i->Xin.CMov32.dst); + return; + case Xin_LoadEX: + mapRegs_X86AMode(m, i->Xin.LoadEX.src); + mapReg(m, &i->Xin.LoadEX.dst); + return; + case Xin_Store: + mapReg(m, &i->Xin.Store.src); + mapRegs_X86AMode(m, i->Xin.Store.dst); + return; default: ppX86Instr(i); vpanic("mapRegs_X86Instr"); diff --git a/VEX/priv/host-x86/x86h_defs.h b/VEX/priv/host-x86/x86h_defs.h index eb8231796c..39d28a5092 100644 --- a/VEX/priv/host-x86/x86h_defs.h +++ b/VEX/priv/host-x86/x86h_defs.h @@ -281,7 +281,7 @@ typedef /* Not and Neg */ struct { X86UnaryOp op; - X86RM* dst; + X86RM* dst; } Unary32; /* DX:AX = AX *s/u r/m16, or EDX:EAX = EAX *s/u r/m32 */ struct { @@ -289,7 +289,7 @@ typedef X86ScalarSz ssz; X86RM* src; } MulL; - /* x86 div/idiv instruction */ + /* x86 div/idiv instruction. Modifies EDX and EAX and reads src. */ struct { Bool syned; X86ScalarSz ssz; diff --git a/VEX/priv/main/vex_main.c b/VEX/priv/main/vex_main.c index 2baa40567f..cac3f77383 100644 --- a/VEX/priv/main/vex_main.c +++ b/VEX/priv/main/vex_main.c @@ -149,14 +149,16 @@ TranslateResult LibVEX_Translate ( /* Turn it into virtual-registerised code. */ vcode = iselBB ( irbb ); -LibVEX_ClearTemporary(True); return TransOK; - vex_printf("\n-------- Virtual registerised code --------\n"); - for (i = 0; i < vcode->arr_used; i++) { - ppInstr(vcode->arr[i]); + if (vex_verbosity > 0) { + vex_printf("\n-------- Virtual registerised code --------\n"); + for (i = 0; i < vcode->arr_used; i++) { + vex_printf("%3d ", i); + ppInstr(vcode->arr[i]); + vex_printf("\n"); + } vex_printf("\n"); } - vex_printf("\n"); /* Register allocate. */ rcode = doRegisterAllocation ( vcode, available_real_regs, @@ -165,15 +167,19 @@ LibVEX_ClearTemporary(True); return TransOK; genSpill, genReload, ppInstr, ppReg ); - vex_printf("\n-------- Post-regalloc code --------\n"); - for (i = 0; i < rcode->arr_used; i++) { - ppInstr(rcode->arr[i]); + if (vex_verbosity > 0) { + vex_printf("\n-------- Post-regalloc code --------\n"); + for (i = 0; i < rcode->arr_used; i++) { + vex_printf("%3d ", i); + ppInstr(rcode->arr[i]); + vex_printf("\n"); + } vex_printf("\n"); } - vex_printf("\n"); /* Assemble, etc. */ - LibVEX_ClearTemporary(True); + // LibVEX_ClearTemporary(True); + LibVEX_ClearTemporary(False); return TransOK; } diff --git a/VEX/test_main.c b/VEX/test_main.c index 15d5dd969b..f5ed09f2ac 100644 --- a/VEX/test_main.c +++ b/VEX/test_main.c @@ -41,6 +41,7 @@ static Char linebuf[N_LINEBUF]; static Char origbuf[N_ORIGBUF]; static Char transbuf[N_TRANSBUF]; +static Bool verbose = True; int main ( int argc, char** argv ) { @@ -63,8 +64,10 @@ int main ( int argc, char** argv ) } LibVEX_Init ( &failure_exit, &log_bytes, - 1, 1, //False, - True, + 1, /* debug_paranoia */ + 1, /* verbosity */ + False, + //True, 100 ); while (!feof(f)) { @@ -82,15 +85,19 @@ int main ( int argc, char** argv ) assert(linebuf[0] == '.'); /* second line is: . byte byte byte etc */ //printf("%s", linebuf); - printf("\n\n============ Basic Block %d, " - "Start %x, nbytes %d ============\n\n", - bb_number, orig_addr, orig_nbytes); + if (verbose) + printf("\n\n============ Basic Block %d, " + "Start %x, nbytes %d ============\n\n", + bb_number, orig_addr, orig_nbytes); assert(orig_nbytes >= 1 && orig_nbytes <= N_ORIGBUF); for (i = 0; i < orig_nbytes; i++) { assert(1 == sscanf(&linebuf[2 + 3*i], "%x", &u)); origbuf[i] = (UChar)u; } + // if (bb_number == 50) exit(1); + { int i; + for (i = 0; i < 1; i++) tres = LibVEX_Translate ( InsnSetX86, InsnSetX86, origbuf, (Addr64)orig_addr, &orig_used, @@ -98,9 +105,11 @@ int main ( int argc, char** argv ) NULL, NULL ); assert(tres == TransOK); assert(orig_used == orig_nbytes); + } } fclose(f); + LibVEX_ClearTemporary(True); #if 0 Int* p;