Skip to content

Commit

Permalink
Merge pull request #3 from uwplse/unstructured-shadows
Browse files Browse the repository at this point in the history
Unstructured shadows
  • Loading branch information
HazardousPeach authored Jun 23, 2016
2 parents 4d70ebb + f590c02 commit 7e079e9
Show file tree
Hide file tree
Showing 22 changed files with 868 additions and 708 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ bench/*.gh
bench/herbie-crosseval/*.gh
bench/herbie-crosseval/*.c
!bench/herbie-crosseval/driver.c
vgcore*
11 changes: 4 additions & 7 deletions bench/diff-roots-simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@

int main(int argc, char** argv){
double x,y;
x = 10e12;
/* for(int i = 0; i < 2; ++i){ */
/* x *= (i + 1) * 10; */
HERBGRIND_BEGIN();
y = sqrt(x + 1) - sqrt(x);
HERBGRIND_END();
/* } */
x = 10e15;
HERBGRIND_BEGIN();
y = sqrt(x + 1) - sqrt(x);
HERBGRIND_END();
printf("%e\n", y);
return 0;
}
216 changes: 141 additions & 75 deletions src/hg_instrument.c

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions src/hg_instrumentOp.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
void instrumentOp(IRSB* sb, Int offset, IRExpr* expr, Addr opAddr){
IRDirty* executeShadowOp;
SizeT arg_size, result_size;
(void)executeShadowOp;
(void)arg_size;
(void)result_size;

// So, I recently learned that valgrind doesn't like passing more
// than three arguments to a c function called by client code. I
Expand Down Expand Up @@ -183,9 +186,9 @@ void instrumentOp(IRSB* sb, Int offset, IRExpr* expr, Addr opAddr){
// Add statements to populate the values we don't know until
// runtime.
addStore(sb, expr->Iex.Unop.arg,
opInfo->args.uargs.arg_value);
&(opInfo->args.uargs.arg_value));
addStore(sb, IRExpr_RdTmp(offset),
opInfo->dest_value);
&(opInfo->dest_value));

// Finally, add the statement to call the shadow op procedure.
executeShadowOp =
Expand Down Expand Up @@ -599,6 +602,7 @@ void instrumentOp(IRSB* sb, Int offset, IRExpr* expr, Addr opAddr){
}
default:
VG_(dmsg)("BAD THINGS!!!!\n");
break;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/hg_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ static void hg_fini(Int exitcode){
VG_(snprintf)(filename, 100, "%s-errors.gh", VG_(args_the_exename));
outfile_path = filename;
}
VG_(printf)("Writing report out to %s\n", outfile_path);
writeReport(outfile_path);
VG_(printf)("Wrote report out to %s\n", outfile_path);
}
// This does any initialization that needs to be done after command
// line processing.
Expand Down
7 changes: 5 additions & 2 deletions src/include/mk_mathreplace.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@


class Op(object):
def __init__(self, func, plain_name, nargs, mpfr_func=None, needsround=True):
def __init__(self, func, plain_name, nargs, mpfr_func=None, needsround=True, precision=64):
self.func = func
self.nargs = nargs
self.plain_name = plain_name
self.needsround = needsround
self.precision = precision
if (mpfr_func == None):
self.mpfr_func = "mpfr_{}".format(func)
else:
Expand Down Expand Up @@ -128,6 +129,7 @@ def write_mathreplace_funcs(ops, fname):
f.write(" case OP_{}: \\\n".format(op.func.upper()))
f.write(" plain_opname = \"{}\"; \\\n".format(op.plain_name))
f.write(" op_symbol = \"{}\"; \\\n".format(op.func))
f.write(" op_precision = {}; \\\n".format(op.precision))
f.write(" break; \\\n")
f.write(" default: \\\n")
f.write(" return; \\\n")
Expand Down Expand Up @@ -239,7 +241,8 @@ def addOp(name, plain_name, nargs,
plain_name + " (float)",
nargs,
mpfr_func=mpfr_fn,
needsround=needsRound))
needsround=needsRound,
precision=32))

addOp("sqrt", "square root", 1)
addOp("cbrt", "cube root", 1)
Expand Down
6 changes: 3 additions & 3 deletions src/runtime/hg_evaluate.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,18 @@ void evaluateOpError(ShadowValue* shadowVal, double actualVal,
}
}

void evaluateOpError_helper(ShadowValue* shadowVal, UWord* valbytes, LocType bytestype, int el_index, Op_Info* opinfo){
void evaluateOpError_helper(ShadowValue* shadowVal, LocType bytestype, int el_index, Op_Info* opinfo){
switch(bytestype){
case Lt_Float:
case Lt_Floatx2:
case Lt_Floatx4:
case Lt_Floatx8:
evaluateOpError(shadowVal, ((float*)valbytes)[el_index], opinfo);
evaluateOpError(shadowVal, ((float*)(opinfo->dest_value))[el_index], opinfo);
break;
case Lt_Double:
case Lt_Doublex2:
case Lt_Doublex4:
evaluateOpError(shadowVal, ((double*)valbytes)[el_index], opinfo);
evaluateOpError(shadowVal, ((double*)(opinfo->dest_value))[el_index], opinfo);
break;
default:
VG_(dmsg)("Hey, those are some big floats! We can't handle those floats!");
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/hg_evaluate.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ void evaluateOpError(ShadowValue* shadowVal, double actualVal, Op_Info* opinfo);
// array of whatever datatype bytestype indicates, and then index into
// it with el_index to get the actual floating point value that we'll
// test against the shadow value.
void evaluateOpError_helper(ShadowValue* shadowVal, UWord* valbytes, LocType bytestype, int el_index, Op_Info* opinfo);
void evaluateOpError_helper(ShadowValue* shadowVal, LocType bytestype, int el_index, Op_Info* opinfo);

#endif
112 changes: 59 additions & 53 deletions src/runtime/hg_mathreplace.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ Addr getCallAddr(void){

void performOp(OpType op, double* result, double* args){
SizeT nargs;
SizeT op_precision;
const HChar* plain_opname;
const HChar* op_symbol;

Expand Down Expand Up @@ -140,14 +141,14 @@ void performOp(OpType op, double* result, double* args){
// library here, and where we can it's being wrapped so doing so
// would result in an infinite loop.
mpfr_t *args_m, res;
ShadowLocation **arg_shadows, *res_shadow;
ShadowValue **arg_shadows, *res_shadow;

// Initialize our 64-bit mpfr arg and shadow, and get the result
// shadow set up.
args_m = VG_(malloc)("wrapped-args", nargs * sizeof(mpfr_t));
arg_shadows = VG_(malloc)("wrapped-shadow", nargs * sizeof(ShadowLocation*));
arg_shadows = VG_(malloc)("wrapped-shadow", nargs * sizeof(ShadowValue*));
for (SizeT i = 0; i < nargs; ++i){
mpfr_init2(args_m[i], 64);
mpfr_init2(args_m[i], op_precision);
// Get the actual value from the pointer they gave us.
mpfr_set_d(args_m[i], args[i], MPFR_RNDN);
// Get the location of the arg source slot in the op structure.
Expand Down Expand Up @@ -192,11 +193,11 @@ void performOp(OpType op, double* result, double* args){
}
// Lookup the address in our shadow hash table to get the shadow
// argument.
arg_shadows[i] = getShadowLocMem((uintptr_t)&(args[i]), args[i],
arg_shadows[i] = getShadowValMem((uintptr_t)&(args[i]), args[i],
i, src_loc_slot);
}
mpfr_init2(res,64);
res_shadow = mkShadowLocation(Lt_Double);
mpfr_init2(res,op_precision);
res_shadow = mkShadowValue();

switch(op){
// This expands to the cases for ops which take one argument and
Expand All @@ -212,20 +213,13 @@ void performOp(OpType op, double* result, double* args){
GET_UNARY_OPS_ROUND_INFO(op)

if (print_inputs){
char *shadowArg1Str;
mpfr_exp_t shadowArg1Expt;

shadowArg1Str = mpfr_get_str(NULL, &shadowArg1Expt, 10, longprint_len,
arg_shadows[0]->values[0].value, MPFR_RNDN);
VG_(printf)("Shadow arg: %se%ld\n",
shadowArg1Str, shadowArg1Expt);
mpfr_free_str(shadowArg1Str);

VG_(printf)("Computed arg: %f\n", args[0]);
VG_(printf)("Shadow arg: ");
printShadowVal(arg_shadows[0]);
VG_(printf)("\nComputed arg: %f\n", args[0]);
}
// Perform the operation on both regular and shadow values.
mpfr_func(res, args_m[0], MPFR_RNDN);
mpfr_func(res_shadow->values[0].value, arg_shadows[0]->values[0].value, MPFR_RNDN);
mpfr_func(res_shadow->value, arg_shadows[0]->value, MPFR_RNDN);
}
break;
// This expands to a bunch of cases for the ops which take one
Expand All @@ -241,7 +235,7 @@ void performOp(OpType op, double* result, double* args){
mpfr_exp_t shadowArg1Expt;

shadowArg1Str = mpfr_get_str(NULL, &shadowArg1Expt, 10, longprint_len,
arg_shadows[0]->values[0].value, MPFR_RNDN);
arg_shadows[0]->value, MPFR_RNDN);
VG_(printf)("Shadow arg: %se%ld\n",
shadowArg1Str, shadowArg1Expt);
mpfr_free_str(shadowArg1Str);
Expand All @@ -250,7 +244,7 @@ void performOp(OpType op, double* result, double* args){
}
// Perform the operation on both regular and shadow values.
mpfr_func(res, args_m[0]);
mpfr_func(res_shadow->values[0].value, arg_shadows[0]->values[0].value);
mpfr_func(res_shadow->value, arg_shadows[0]->value);
}
break;
// This expands to a bunch of cases for operations which take two
Expand All @@ -266,9 +260,9 @@ void performOp(OpType op, double* result, double* args){
mpfr_exp_t shadowArg1Expt, shadowArg2Expt;

shadowArg1Str = mpfr_get_str(NULL, &shadowArg1Expt, 10, longprint_len,
arg_shadows[0]->values[0].value, MPFR_RNDN);
arg_shadows[0]->value, MPFR_RNDN);
shadowArg2Str = mpfr_get_str(NULL, &shadowArg2Expt, 10, longprint_len,
arg_shadows[1]->values[0].value, MPFR_RNDN);
arg_shadows[1]->value, MPFR_RNDN);
VG_(printf)("Shadow first arg: %se%ld\nShadow second arg: %se%ld\n",
shadowArg1Str, shadowArg1Expt, shadowArg2Str, shadowArg2Expt);
mpfr_free_str(shadowArg1Str);
Expand All @@ -280,9 +274,9 @@ void performOp(OpType op, double* result, double* args){
}
// Perform the operation on both regular and shadow values.
mpfr_func(res, args_m[0], args_m[1], MPFR_RNDN);
mpfr_func(res_shadow->values[0].value,
arg_shadows[0]->values[0].value,
arg_shadows[1]->values[0].value, MPFR_RNDN);
mpfr_func(res_shadow->value,
arg_shadows[0]->value,
arg_shadows[1]->value, MPFR_RNDN);
}
break;
// This expands to a bunch of cases for operations which take two
Expand All @@ -298,11 +292,11 @@ void performOp(OpType op, double* result, double* args){
mpfr_exp_t shadowArg1Expt, shadowArg2Expt, shadowArg3Expt;

shadowArg1Str = mpfr_get_str(NULL, &shadowArg1Expt, 10, longprint_len,
arg_shadows[0]->values[0].value, MPFR_RNDN);
arg_shadows[0]->value, MPFR_RNDN);
shadowArg2Str = mpfr_get_str(NULL, &shadowArg2Expt, 10, longprint_len,
arg_shadows[1]->values[0].value, MPFR_RNDN);
arg_shadows[1]->value, MPFR_RNDN);
shadowArg3Str = mpfr_get_str(NULL, &shadowArg3Expt, 10, longprint_len,
arg_shadows[2]->values[0].value, MPFR_RNDN);
arg_shadows[2]->value, MPFR_RNDN);
VG_(printf)("Shadow first arg: %se%ld\n"
"Shadow second arg: %se%ld\n"
"Shadow third arg: %se%ld\n",
Expand All @@ -320,10 +314,10 @@ void performOp(OpType op, double* result, double* args){
}
// Perform the operation on both regular and shadow values.
mpfr_func(res, args_m[0], args_m[1], args_m[2], MPFR_RNDN);
mpfr_func(res_shadow->values[0].value,
arg_shadows[0]->values[0].value,
arg_shadows[1]->values[0].value,
arg_shadows[2]->values[0].value,
mpfr_func(res_shadow->value,
arg_shadows[0]->value,
arg_shadows[1]->value,
arg_shadows[2]->value,
MPFR_RNDN);
}
break;
Expand All @@ -333,27 +327,39 @@ void performOp(OpType op, double* result, double* args){
// were given to the result memory.
*result = mpfr_get_d(res, MPFR_RNDN);
setMem((uintptr_t)result, res_shadow);
// Disown a reference for this since it gets one when it starts up
// (to keep it alive), and putting it in memory adds another.
disownSV(res_shadow);

// Set up the ast record of this operation.
switch(nargs){
case 1:
initValueBranchAST(&(res_shadow->values[0]), entry->info, nargs,
&(arg_shadows[0]->values[0]));
initValueBranchAST(res_shadow, entry->info, nargs,
arg_shadows[0]);
break;
case 2:
initValueBranchAST(&(res_shadow->values[0]), entry->info, nargs,
&(arg_shadows[0]->values[0]),
&(arg_shadows[1]->values[0]));
initValueBranchAST(res_shadow, entry->info, nargs,
arg_shadows[0],
arg_shadows[1]);
break;
case 3:
initValueBranchAST(&(res_shadow->values[0]), entry->info, nargs,
&(arg_shadows[0]->values[0]),
&(arg_shadows[1]->values[0]),
&(arg_shadows[2]->values[0]));
initValueBranchAST(res_shadow, entry->info, nargs,
arg_shadows[0],
arg_shadows[1],
arg_shadows[2]);
break;
}
// And finally, evaluate the error of the operation.
evaluateOpError(&(res_shadow->values[0]), *result, entry->info);
evaluateOpError(res_shadow, *result, entry->info);

// If we're printing debug info about where values are flowing, let
// the user know that we're putting the result of this operation in
// memory.
if (print_moves && res_shadow != NULL){
VG_(printf)("Putting shadow value ");
printShadowVal(res_shadow);
VG_(printf)(" in memory address %p.\n", result);
}

// And free up the arrays we malloc for variable number of args.
for (int i = 0; i < nargs; ++i){
Expand All @@ -364,22 +370,22 @@ void performOp(OpType op, double* result, double* args){
VG_(free)(arg_shadows);
}

ShadowLocation* getShadowLocMem(Addr addr, double float_arg,
Int argIndex, Op_Info** arg_src){
ShadowLocation* loc = getMem(addr);
if (loc != NULL) return loc;

if (print_moves)
VG_(printf)("Creating new shadow location at addr %lx\n", addr);
ShadowValue* getShadowValMem(Addr addr, double float_arg,
Int argIndex, Op_Info** arg_src){
ShadowValue* val = getMem(addr);
if (val != NULL) return val;

if (getSavedArg(argIndex) != NULL){
return getSavedArg(argIndex);
}

loc = mkShadowLocation(Lt_Double);
setMem(addr, loc);
if (print_moves)
VG_(printf)("Creating new shadow location at addr %p\n", (void*)(uintptr_t)addr);

val = mkShadowValue();
setMem(addr, val);

mpfr_set_d(loc->values[0].value, float_arg, MPFR_RNDN);
initValueLeafAST(&(loc->values[0]), arg_src);
return loc;
mpfr_set_d(val->value, float_arg, MPFR_RNDN);
initValueLeafAST(val, arg_src);
return val;
}
4 changes: 2 additions & 2 deletions src/runtime/hg_mathreplace.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
extern VgHashTable* callToOpInfoMap;

void performOp(OpType op, double* result, double* args);
ShadowLocation* getShadowLocMem(Addr addr, double float_arg,
Int argIndex, Op_Info** arg_src);
ShadowValue* getShadowValMem(Addr addr, double float_arg,
Int argIndex, Op_Info** arg_src);

// This function, called from within a math replacement function,
// get's the address of the call site for that function in client
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/hg_op_tracker.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void writeReport(const HChar* filename){
Int file_d = sr_Res(file_result);

if (tracked_ops == NULL){
VG_(write)(file_d, "No errors found.\n", 18);
VG_(write)(file_d, "No errors found.\n", 17);
VG_(close)(file_d);
return;
}
Expand Down
Loading

0 comments on commit 7e079e9

Please sign in to comment.