From: Julian Seward Date: Sun, 27 Jun 2004 10:42:44 +0000 (+0000) Subject: Redo IR data structures using tagged unions. X-Git-Tag: svn/VALGRIND_3_0_1^2~1309 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8b1698d21e286ddce99f70743744312192484e2f;p=thirdparty%2Fvalgrind.git Redo IR data structures using tagged unions. git-svn-id: svn://svn.valgrind.org/vex/trunk@25 --- diff --git a/VEX/Makefile b/VEX/Makefile index f8dde35caf..0c3f6f08bf 100644 --- a/VEX/Makefile +++ b/VEX/Makefile @@ -1,7 +1,8 @@ INCLUDES = include/basictypes.h -OBJS = basictypes.o arena.o linker.o dispatch.o +##OBJS = basictypes.o ir_defs.o arena.o linker.o dispatch.o +OBJS = basictypes.o ir_defs.o CC_OPTS = -g -Wall -Iinclude @@ -13,6 +14,8 @@ clean: basictypes.o: basictypes.c $(INCLUDES) gcc $(CC_OPTS) -c basictypes.c +ir_defs.o: ir_defs.c $(INCLUDES) + gcc $(CC_OPTS) -c ir_defs.c arena.o: arena.c $(INCLUDES) gcc $(CC_OPTS) -c arena.c linker.o: linker.c $(INCLUDES) diff --git a/VEX/include/ir_defs.h b/VEX/include/ir_defs.h index e2317f87d9..7063a185b8 100644 --- a/VEX/include/ir_defs.h +++ b/VEX/include/ir_defs.h @@ -9,14 +9,20 @@ #ifndef __IR_DEFS_H #define __IR_DEFS_H -//#include "storage.h" -#include +#include /* FILE* */ /*---------------------------------------------------------------*/ /*--- Type definitions for the IR ---*/ /*---------------------------------------------------------------*/ +/* Types */ + +typedef + enum { Ity_Bit, Ity_I8, Ity_I16, Ity_I32, Ity_I64 } + IRType; + + /* Constants */ typedef @@ -24,7 +30,7 @@ typedef IRConstTag; typedef - struct { + struct _IRConst { IRConstTag tag; union { UChar u8; @@ -41,13 +47,6 @@ typedef typedef int IRTemp; -/* Types */ - -typedef - enum { Ity_Bit, Ity_I8, Ity_I16, Ity_I32, Ity_I64 } - IRType; - - /* Binary and unary ops */ typedef @@ -60,13 +59,59 @@ typedef Iop_Shl32, Iop_Shr32, Iop_Sar32, - // Tags for unary ops + /* Tags for unary ops */ Iop_Not32, Iop_Neg32 } IROp; +/* Expressions + +data Expr + = GET Int Int -- offset, size + | TMP Temp -- value of temporary + | BINOP Op Expr Expr -- binary op + | UNOP Op Expr -- unary op + | LDle Type Expr -- load of the given type, Expr:: 32 or 64 + | CONST Const -- 8/16/32/64-bit int constant +*/ +typedef + enum { Iex_Get, Iex_Tmp, Iex_Binop, Iex_Unop, Iex_LDle, Iex_Const } + IRExprTag; + +typedef + struct _IRExpr { + IRExprTag tag; + union { + struct { + Int offset; + Int size; + } Get; + struct { + IRTemp tmp; + } Tmp; + struct { + IROp op; + struct _IRExpr* arg1; + struct _IRExpr* arg2; + } Binop; + struct { + IROp op; + struct _IRExpr* arg; + } Unop; + struct { + IRType ty; + struct _IRExpr* addr; + } LDle; + struct { + struct _IRConst* con; + } Const; + } Iex; + } + IRExpr; + + /* Statements: data Stmt @@ -119,12 +164,12 @@ typedef IRNextTag tag; union { struct { - IRConst dst; + struct _IRConst* dst; } UJump; struct { - struct _IRExpr* cond; - IRConst dst0; - IRConst dst1; + struct _IRExpr* cond; + struct _IRConst* dst0; + struct _IRConst* dst1; } CJump01; struct { struct _IRExpr* dst; @@ -134,59 +179,11 @@ typedef IRNext; -/* Expressions - -data Expr - = GET Int Int -- offset, size - | TMP Temp -- value of temporary - | BINOP Op Expr Expr -- binary op - | UNOP Op Expr -- unary op - | LDle Type Expr -- load of the given type, Expr:: 32 or 64 - | CONST Const -- 8/16/32/64-bit int constant -*/ -typedef - enum { Iex_Get, Iex_Tmp, Iex_Binop, Iex_Unop, Iex_LDle, Iex_Const } - IRExprTag; - -typedef - struct _IRExpr { - IRExprTag tag; - union { - struct { - Int offset; - Int size; - } Get; - struct { - IRTemp tmp; - } Tmp; - struct { - IROp op; - struct _IRExpr* arg1; - struct _IRExpr* arg2; - } Binop; - struct { - IROp op; - struct _IrExpr* arg; - } Unop; - struct { - IRType ty; - struct _IRExpr* addr; - } LDle; - struct { - IRConst con; - } Const; - } Iex; - } - IRExpr; - - /* Basic blocks contain 3 fields: - An association list, giving a type for each temp - A list of statements - A Next */ -#define IR_BB 190 /* arity = 3 */ - typedef struct _IRBB { struct _IRStmt* stmts; @@ -200,40 +197,33 @@ typedef /*---------------------------------------------------------------*/ /* Printers ... */ -extern void ppIRBB ( FILE* f, IRBB* ); -extern void ppIRNext ( FILE* f, IRNext* ); -extern void ppIRStmt ( FILE* f, IRStmt* ); -extern void ppIRExpr ( FILE* f, IRExpr* ); -extern void ppIRTemp ( FILE* f, IRTemp* ); -extern void ppIRType ( FILE* f, IRType* ); +extern void ppIRType ( FILE* f, IRType ); extern void ppIRConst ( FILE* f, IRConst* ); +extern void ppIRTemp ( FILE* f, IRTemp ); extern void ppIROp ( FILE* f, IROp ); +extern void ppIRExpr ( FILE* f, IRExpr* ); +extern void ppIRStmt ( FILE* f, IRStmt* ); +extern void ppIRNext ( FILE* f, IRNext* ); +extern void ppIRBB ( FILE* f, IRBB* ); -/* Constructors -- IRBB */ -extern IRBB* mkBB ( IRStmt* stmts, IRNext* next ); - -/* Constructors -- IRNext */ -extern IRNext* mkUJump ( IRConst* dst ); +/* Constructors -- IRExpr */ +extern IRExpr* mkExGet ( Int off, Int sz ); +extern IRExpr* mkExTmp ( IRTemp tmp ); +extern IRExpr* mkExBinop ( IROp op, IRExpr* arg1, IRExpr* arg2 ); +extern IRExpr* mkExUnop ( IROp op, IRExpr* arg ); +extern IRExpr* mkExLDle ( IRType ty, IRExpr* addr ); +extern IRExpr* mkExConst ( IRConst* con ); /* Constructors -- IRStmt */ extern IRStmt* mkStPut ( Int off, Int sz, IRExpr* value ); extern IRStmt* mkStTmp ( IRTemp tmp, IRExpr* expr ); extern IRStmt* mkStSTle ( IRExpr* addr, IRExpr* value ); -/* Constructors -- IRExpr */ -extern IRExpr mkExGet ( Int off, Int sz ); -extern IRExpr mkExTmp ( IRTemp tmp ); -extern IRExpr mkExBinop ( IROp op, IRExpr* arg1, IRExpr* arg2 ); -extern IRExpr mkExUnop ( IROp op, IRExpr* arg ); -extern IRExpr mkExLDle ( IRType ty, IRExpr* addr ); -extern IRExpr mkExConst ( IRConst* con ); - -/* Constructors -- IRTemp */ -extern IRTemp mkIRTemp ( Int n ); - -/* Constructors -- IRType */ -/* Constructors -- IRAtomI */ -/* Constructors -- IROp */ +/* Constructors -- IRNext */ +extern IRNext* mkNxUJump ( IRConst* dst ); + +/* Constructors -- IRBB */ +extern IRBB* mkIRBB ( IRStmt* stmts, IRNext* next ); #endif /* ndef __IR_DEFS_H */ diff --git a/VEX/ir_defs.c b/VEX/ir_defs.c index 35198bd27e..a4981acd02 100644 --- a/VEX/ir_defs.c +++ b/VEX/ir_defs.c @@ -6,214 +6,157 @@ /*--- ---*/ /*---------------------------------------------------------------*/ -#include - +#include "basictypes.h" #include "ir_defs.h" - -/*---------------------------------------------------------------*/ -/*--- Registering the storage tags ---*/ -/*---------------------------------------------------------------*/ - -void register_IR_tags ( void ) -{ - storage_register_tag(IR_TMP, 1, "tmp"); - - storage_register_tag(TY_Bit, 0, "Bit"); - storage_register_tag(TY_I8, 0, "I8"); - storage_register_tag(TY_I16, 0, "I16"); - storage_register_tag(TY_I32, 0, "I32"); - storage_register_tag(TY_I64, 0, "I64"); - - storage_register_tag(OP_Add32, 2, "Add32"); - storage_register_tag(OP_Sub32, 2, "Sub32"); - storage_register_tag(OP_Mul32, 2, "Mul32"); - storage_register_tag(OP_Or32, 2, "Or32" ); - storage_register_tag(OP_And32, 2, "And32"); - storage_register_tag(OP_Xor32, 2, "Xor32"); - storage_register_tag(OP_Shl32, 2, "Shl32"); - storage_register_tag(OP_Shr32, 2, "Shr32"); - storage_register_tag(OP_Sar32, 2, "Sar32"); - - storage_register_tag(OP_Not32, 1, "Not32"); - storage_register_tag(OP_Neg32, 1, "Neg32"); - - storage_register_tag(ST_Put, 3, "ST_Put"); - storage_register_tag(ST_Tmp, 2, "ST_Tmp"); - storage_register_tag(ST_STle, 2, "ST_STle"); - - storage_register_tag(NX_UJump, 1, "NX_UJump"); - storage_register_tag(NX_CJump01, 3, "NX_CJump01"); - storage_register_tag(NX_IJump, 1, "NX_IJump"); - - storage_register_tag(EX_Get, 2, "EX_Get"); - storage_register_tag(EX_Tmp, 1, "EX_Tmp"); - storage_register_tag(EX_Binop, 3, "EX_Binop"); - storage_register_tag(EX_Unop, 2, "EX_Unop"); - storage_register_tag(EX_LDle, 2, "EX_LDle"); - storage_register_tag(EX_AtomI, 1, "EX_AtomI"); - - storage_register_tag(IR_BB, 3, "IR_BB"); -} - +#include /*---------------------------------------------------------------*/ /*--- Printing the IR ---*/ /*---------------------------------------------------------------*/ -void ppGuestAddr ( FILE* f, GuestAddr ga ) +void ppIRType ( FILE* f, IRType ty ) { - switch (getTag(ga)) { - case TagWord32: fprintf(f, "0x%x", getWord32(ga)); break; - case TagWord64: fprintf(f, "0x%llx", getWord64(ga)); break; - default: panic("ppGuestAddr"); + switch (ty) { + case Ity_Bit: fprintf(f, "Bit"); break; + case Ity_I8: fprintf(f, "I8"); break; + case Ity_I16: fprintf(f, "I16"); break; + case Ity_I32: fprintf(f, "I32"); break; + case Ity_I64: fprintf(f, "I64"); break; + default: panic("ppIRType"); } } -void ppIROp ( FILE* f, IROp op ) +void ppIRConst ( FILE* f, IRConst* con ) { - switch (getTag(op)) { - case OP_Add32: fprintf(f, "Add32"); break; - case OP_Sub32: fprintf(f, "Sub32"); break; - case OP_Mul32: fprintf(f, "Mul32"); break; - case OP_Or32: fprintf(f, "Or32"); break; - case OP_And32: fprintf(f, "And32"); break; - case OP_Xor32: fprintf(f, "Xor32"); break; - case OP_Shl32: fprintf(f, "Shl32"); break; - case OP_Shr32: fprintf(f, "Shr32"); break; - case OP_Sar32: fprintf(f, "Sar32"); break; - case OP_Not32: fprintf(f, "Not32"); break; - case OP_Neg32: fprintf(f, "Neg32"); break; - default: panic("ppIROp"); + switch (con->tag) { + case Ico_u8: fprintf(f, "0x%x", (UInt)(con->Ico.u8)); break; + case Ico_u16: fprintf(f, "0x%x", (UInt)(con->Ico.u16)); break; + case Ico_u32: fprintf(f, "0x%x", (UInt)(con->Ico.u32)); break; + case Ico_u64: fprintf(f, "0x%llx", (ULong)(con->Ico.u64)); break; + default: panic("ppIRConst"); } } -void ppIRAtomI ( FILE* f, IRAtomI at ) +void ppIRTemp ( FILE* f, IRTemp tmp ) { - switch (getTag(at)) { - case TagWord8: fprintf(f, "0x%x", getWord8(at)); break; - case TagWord16: fprintf(f, "0x%x", getWord16(at)); break; - case TagWord32: fprintf(f, "0x%x", getWord32(at)); break; - case TagWord64: fprintf(f, "0x%llx", getWord64(at)); break; - default: panic("ppIRAtom"); - } + fprintf(f, "t%d", tmp); } -void ppIRType ( FILE* f, IRType ty ) + +void ppIROp ( FILE* f, IROp op ) { - switch (getTag(ty)) { - case TY_Bit: fprintf(f, "Bit"); break; - case TY_I8: fprintf(f, "I8"); break; - case TY_I16: fprintf(f, "I16"); break; - case TY_I32: fprintf(f, "I32"); break; - case TY_I64: fprintf(f, "I64"); break; - default: panic("ppIRType"); + switch (op) { + case Iop_Add32: fprintf(f, "Add32"); break; + case Iop_Sub32: fprintf(f, "Sub32"); break; + case Iop_Mul32: fprintf(f, "Mul32"); break; + case Iop_Or32: fprintf(f, "Or32"); break; + case Iop_And32: fprintf(f, "And32"); break; + case Iop_Xor32: fprintf(f, "Xor32"); break; + case Iop_Shl32: fprintf(f, "Shl32"); break; + case Iop_Shr32: fprintf(f, "Shr32"); break; + case Iop_Sar32: fprintf(f, "Sar32"); break; + case Iop_Not32: fprintf(f, "Not32"); break; + case Iop_Neg32: fprintf(f, "Neg32"); break; + default: panic("ppIROp"); } } -void ppIRExpr ( FILE* f, IRExpr expr ) +void ppIRExpr ( FILE* f, IRExpr* e ) { - switch (getTag(expr)) { - case EX_Get: - fprintf(f, "GET(%d,%d)", sel21(expr), sel22(expr)); + switch (e->tag) { + case Iex_Get: + fprintf(f, "GET(%d,%d)", e->Iex.Get.offset, e->Iex.Get.size); break; - case EX_Tmp: - ppIRTemp(f,sel11(expr)); + case Iex_Tmp: + ppIRTemp(f, e->Iex.Tmp.tmp); break; - case EX_Binop: - ppIROp(f,sel31(expr)); + case Iex_Binop: + ppIROp(f, e->Iex.Binop.op); fprintf(f, "("); - ppIRExpr(f,sel32(expr)); + ppIRExpr(f, e->Iex.Binop.arg1); fprintf(f, ","); - ppIRExpr(f,sel33(expr)); + ppIRExpr(f, e->Iex.Binop.arg2); fprintf(f, ")"); break; - case EX_Unop: - ppIROp(f,sel21(expr)); + case Iex_Unop: + ppIROp(f, e->Iex.Unop.op); fprintf(f, "("); - ppIRExpr(f,sel22(expr)); + ppIRExpr(f, e->Iex.Unop.arg); fprintf(f, ")"); break; - case EX_LDle: + case Iex_LDle: fprintf(f, "LDle<"); - ppIRType(f, sel21(expr)); + ppIRType(f, e->Iex.LDle.ty); fprintf(f,">("); - ppIRExpr(f, sel22(expr)); + ppIRExpr(f, e->Iex.LDle.addr); fprintf(f,")"); break; - case EX_AtomI: - ppIRAtomI(f, sel11(expr)); + case Iex_Const: + ppIRConst(f, e->Iex.Const.con); break; default: panic("ppIExpr"); } } -void ppIRTemp ( FILE* f, IRTemp tmp ) +void ppIRStmt ( FILE* f, IRStmt* s ) { - switch (getTag(tmp)) { - case IR_TMP: fprintf(f, "t%d", sel11(tmp)); break; - default: panic("ppIRTemp"); - } -} - -void ppIRStmt ( FILE* f, IRStmt stmt ) -{ - switch (getTag(stmt)) { - case ST_Put: - fprintf(f, "Put(%d,%d) = ", sel31(stmt), sel32(stmt)); - ppIRExpr(f, sel33(stmt)); + switch (s->tag) { + case Ist_Put: + fprintf(f, "Put(%d,%d) = ", s->Ist.Put.offset, s->Ist.Put.size); + ppIRExpr(f, s->Ist.Put.expr); break; - case ST_Tmp: - ppIRTemp(f, sel21(stmt)); + case Ist_Tmp: + ppIRTemp(f, s->Ist.Tmp.tmp); fprintf(f," = "); - ppIRExpr(f, sel22(stmt)); + ppIRExpr(f, s->Ist.Tmp.expr); break; - case ST_STle: + case Ist_STle: fprintf(f, "STle("); - ppIRExpr(f, sel21(stmt)); + ppIRExpr(f, s->Ist.STle.addr); fprintf(f, ") = "); - ppIRExpr(f, sel22(stmt)); + ppIRExpr(f, s->Ist.STle.data); break; default: panic("ppIRStmt"); } } -void ppIRNext ( FILE* f, IRNext next ) +void ppIRNext ( FILE* f, IRNext* nx ) { - switch (getTag(next)) { - case NX_UJump: + switch (nx->tag) { + case Inx_UJump: fprintf(f, "UJump "); - ppGuestAddr(f,sel11(next)); + ppIRConst(f, nx->Inx.UJump.dst); break; - case NX_CJump01: + case Inx_CJump01: fprintf(f,"CJump01 ("); - ppIRExpr(f,sel31(next)); + ppIRExpr(f, nx->Inx.CJump01.cond); fprintf(f, ") "); - ppGuestAddr(f,sel32(next)); + ppIRConst(f, nx->Inx.CJump01.dst0); fprintf(f, " "); - ppGuestAddr(f,sel33(next)); - case NX_IJump: + ppIRConst(f, nx->Inx.CJump01.dst1); + break; + case Inx_IJump: fprintf(f, "IJump "); - ppIRExpr(f,sel11(next)); + ppIRExpr(f, nx->Inx.IJump.dst); break; default: panic("ppIRNext"); } } -void ppIRBB ( FILE* f, IRBB bb ) +void ppIRBB ( FILE* f, IRBB* bb ) { - Cell sts; - assert(getTag(bb) == IR_BB); - for (sts = sel32(bb); nonNil(sts); sts=tail(sts)) { + IRStmt* s; + for (s = bb->stmts; s; s = s->link) { fprintf(f, " "); - ppIRStmt(f,head(sts)); + ppIRStmt(f, s); fprintf(f, "\n"); } fprintf(f, " "); - ppIRNext(f,sel33(bb)); + ppIRNext(f, bb->next); fprintf(f, "\n"); } @@ -222,50 +165,96 @@ void ppIRBB ( FILE* f, IRBB bb ) /*--- Constructors ---*/ /*---------------------------------------------------------------*/ -/* Constructors -- IRBB */ -IRBB mkBB ( AList tys, List stmts, IRNext next ) { - return tuple3(IR_BB, tys, stmts, next); -} +/* Constructors -- IRExpr */ -/* Constructors -- IRNext */ -IRNext mkUJump ( GuestAddr dst ) { - return tuple1 ( NX_UJump, dst ); +IRExpr* mkExGet ( Int off, Int sz ) { + IRExpr* e = malloc(sizeof(IRExpr)); + e->tag = Iex_Get; + e->Iex.Get.offset = off; + e->Iex.Get.size = sz; + return e; } - -/* Constructors -- IRStmt */ -IRStmt mkSTPut ( Int off, Int sz, IRExpr value ) { - return tuple3 ( ST_Put, off, sz, value); +IRExpr* mkExTmp ( IRTemp tmp ) { + IRExpr* e = malloc(sizeof(IRExpr)); + e->tag = Iex_Tmp; + e->Iex.Tmp.tmp = tmp; + return e; } -IRStmt mkSTTmp ( IRTemp tmp, IRExpr expr ) { - return tuple2 ( ST_Tmp, tmp, expr ); +IRExpr* mkExBinop ( IROp op, IRExpr* arg1, IRExpr* arg2 ) { + IRExpr* e = malloc(sizeof(IRExpr)); + e->tag = Iex_Binop; + e->Iex.Binop.op = op; + e->Iex.Binop.arg1 = arg1; + e->Iex.Binop.arg2 = arg2; + return e; } -IRStmt mkSTSTle ( IRExpr addr, IRExpr value ) { - return tuple2 ( ST_STle, addr, value ); +IRExpr* mkExUnop ( IROp op, IRExpr* arg ) { + IRExpr* e = malloc(sizeof(IRExpr)); + e->tag = Iex_Unop; + e->Iex.Unop.op = op; + e->Iex.Unop.arg = arg; + return e; } - -/* Constructors -- IRExpr */ -IRExpr mkEXGet ( Int off, Int sz ) { - return tuple2 ( EX_Get, off, sz ); +IRExpr* mkExLDle ( IRType ty, IRExpr* addr ) { + IRExpr* e = malloc(sizeof(IRExpr)); + e->tag = Iex_LDle; + e->Iex.LDle.ty = ty; + e->Iex.LDle.addr = addr; + return e; } -IRExpr mkEXTmp ( IRTemp tmp ) { - return tuple1 ( EX_Tmp, tmp ); +IRExpr* mkExConst ( IRConst* con ) { + IRExpr* e = malloc(sizeof(IRExpr)); + e->tag = Iex_Const; + e->Iex.Const.con = con; + return e; } -IRExpr mkEXBinop ( IROp op, IRExpr arg1, IRExpr arg2 ) { - return tuple3 ( EX_Binop, op, arg1, arg2 ); + + +/* Constructors -- IRStmt */ + +IRStmt* mkStPut ( Int off, Int sz, IRExpr* value ) { + IRStmt* s = malloc(sizeof(IRStmt)); + s->tag = Ist_Put; + s->Ist.Put.offset = off; + s->Ist.Put.size = sz; + s->Ist.Put.expr = value; + return s; } -IRExpr mkEXUnop ( IROp op, IRExpr arg ) { - return tuple2 ( EX_Unop, op, arg ); +IRStmt* mkStTmp ( IRTemp tmp, IRExpr* expr ) { + IRStmt* s = malloc(sizeof(IRStmt)); + s->tag = Ist_Tmp; + s->Ist.Tmp.tmp = tmp; + s->Ist.Tmp.expr = expr; + return s; } -IRExpr mkEXLDle ( IRType ty, IRExpr addr ) { - return tuple2 ( EX_LDle, ty, addr ); +IRStmt* mkStSTle ( IRExpr* addr, IRExpr* value ) { + IRStmt* s = malloc(sizeof(IRStmt)); + s->tag = Ist_STle; + s->Ist.STle.addr = addr; + s->Ist.STle.data = value; + return s; } -IRExpr mkEXAtomI ( IRAtomI atom ) { - return tuple1 ( EX_AtomI, atom ); + + +/* Constructors -- IRNext */ + +IRNext* mkNxUJump ( IRConst* dst ) { + IRNext* nx = malloc(sizeof(IRNext)); + nx->tag = Inx_UJump; + nx->Inx.UJump.dst = dst; + return nx; } -/* Constructors -- IRTemp */ -IRTemp mkIRTemp ( Int n ) { - return tuple1 ( IR_TMP, n ); + +/* Constructors -- IRBB */ + +IRBB* mkIRBB ( IRStmt* stmts, IRNext* next ) { + IRBB* bb = malloc(sizeof(IRBB)); + bb->stmts = stmts; + bb->next = next; + return bb; } + +