All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] floating-point literals
@ 2017-04-12  9:29 Luc Van Oostenryck
  2017-04-12  9:29 ` [PATCH 1/2] add OP_SETFVAL Luc Van Oostenryck
  2017-04-12  9:29 ` [PATCH 2/2] CSE: support CSE of floating-point literal Luc Van Oostenryck
  0 siblings, 2 replies; 3+ messages in thread
From: Luc Van Oostenryck @ 2017-04-12  9:29 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

The goal of this series is to simplify the handling
of floating-point literals and as an added bonus, to
make possible the CSE of those literals.

This series is available at:
	git://github.com/lucvoo/sparse.git cse-setfval
based on commit:
	604e7ef9c37100c4ca3dc0b3bee00d114e265684 (fix-f2i-casts)
up to commit:
	c9585071d02590f40175ea90c395d15ef70e9a1e

Luc Van Oostenryck (2):
  add OP_SETFVAL
  CSE: support CSE of floating-point literal

 Documentation/instructions.txt      | 12 ++++++----
 cse.c                               | 11 +++++++++
 linearize.c                         | 18 ++++++++++----
 linearize.h                         |  4 ++++
 liveness.c                          |  1 +
 simplify.c                          |  1 +
 sparse-llvm.c                       | 16 +++++++++----
 validation/cast-constant-to-float.c |  6 ++---
 validation/cast-constants.c         | 20 ++++++++--------
 validation/fp-ops.c                 |  2 +-
 validation/optim/bool-context-fp.c  | 47 +++++++++++++++++++++++++++++++++++++
 validation/optim/cse-setfval.c      | 12 ++++++++++
 12 files changed, 123 insertions(+), 27 deletions(-)
 create mode 100644 validation/optim/bool-context-fp.c
 create mode 100644 validation/optim/cse-setfval.c

-- 
2.12.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] add OP_SETFVAL
  2017-04-12  9:29 [PATCH 0/2] floating-point literals Luc Van Oostenryck
@ 2017-04-12  9:29 ` Luc Van Oostenryck
  2017-04-12  9:29 ` [PATCH 2/2] CSE: support CSE of floating-point literal Luc Van Oostenryck
  1 sibling, 0 replies; 3+ messages in thread
From: Luc Van Oostenryck @ 2017-04-12  9:29 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

OP_SETVAL is used to create floating-point and string
as well as labels-as-values. This multi-purpose aspect
sometimes make things a bit more complicated.

Change this by using a new instruction for the direct
creation of floating-point literals without needing
to have an intermediate EXPR_FVALUE.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 Documentation/instructions.txt      | 12 ++++++----
 linearize.c                         | 18 ++++++++++----
 linearize.h                         |  4 ++++
 liveness.c                          |  1 +
 simplify.c                          |  1 +
 sparse-llvm.c                       | 16 +++++++++----
 validation/cast-constant-to-float.c |  6 ++---
 validation/cast-constants.c         | 20 ++++++++--------
 validation/fp-ops.c                 |  2 +-
 validation/optim/bool-context-fp.c  | 47 +++++++++++++++++++++++++++++++++++++
 10 files changed, 100 insertions(+), 27 deletions(-)
 create mode 100644 validation/optim/bool-context-fp.c

diff --git a/Documentation/instructions.txt b/Documentation/instructions.txt
index b8d3d6bbc..236811daf 100644
--- a/Documentation/instructions.txt
+++ b/Documentation/instructions.txt
@@ -199,11 +199,15 @@ Create a pseudo corresponding to the address of a symbol.
 - .symbol: (pseudo_t) input symbol (alias .src)
 - .target: symbol's address
 
+=== OP_SETFVAL ===
+Create a pseudo corresponding to a floating-point literal.
+- .fvalue: the literal's value (long double)
+- .target: the corresponding pseudo
+- .type: type of the literal & .target
+
 === OP_SETVAL ===
-Create a pseudo corresponding to a value.
-The value is given as an expression EXPR_STRING, EXPR_FVALUE or
-EXPR_LABEL (pseudos for integral constants are directly created
-at linearization and doesn't need this instruction)
+Create a pseudo corresponding to a string literal or a label-as-value.
+The value is given as an expression EXPR_STRING or EXPR_LABEL.
 - .val: (expression) input expression
 - .target: the resulting value
 - .type: type of .target, the value
diff --git a/linearize.c b/linearize.c
index 902d45087..9fda0a1ad 100644
--- a/linearize.c
+++ b/linearize.c
@@ -245,6 +245,7 @@ static const char *opcodes[] = {
 	[OP_LOAD] = "load",
 	[OP_STORE] = "store",
 	[OP_SETVAL] = "set",
+	[OP_SETFVAL] = "setfval",
 	[OP_SYMADDR] = "symaddr",
 	[OP_GET_ELEMENT_PTR] = "getelem",
 
@@ -386,6 +387,11 @@ const char *show_instruction(struct instruction *insn)
 		}
 		break;
 	}
+	case OP_SETFVAL:
+		buf += sprintf(buf, "%s <- ", show_pseudo(insn->target));
+		buf += sprintf(buf, "%Lf", insn->fvalue);
+		break;
+
 	case OP_SWITCH: {
 		struct multijmp *jmp;
 		buf += sprintf(buf, "%s", show_pseudo(insn->cond));
@@ -1018,12 +1024,10 @@ static pseudo_t add_setval(struct entrypoint *ep, struct symbol *ctype, struct e
 
 static pseudo_t add_setfval(struct entrypoint *ep, struct symbol *ctype, long double fval)
 {
-	struct instruction *insn = alloc_typed_instruction(OP_SETVAL, ctype);
-	struct expression *expr = alloc_expression(insn->pos, EXPR_FVALUE);
+	struct instruction *insn = alloc_typed_instruction(OP_SETFVAL, ctype);
 	pseudo_t target = alloc_pseudo(insn);
 	insn->target = target;
-	insn->val = expr;
-	expr->fvalue = fval;
+	insn->fvalue = fval;
 	add_one_insn(ep, insn);
 	return target;
 }
@@ -1629,9 +1633,13 @@ pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr)
 	case EXPR_VALUE:
 		return value_pseudo(expr->value);
 
-	case EXPR_STRING: case EXPR_FVALUE: case EXPR_LABEL:
+	case EXPR_STRING:
+	case EXPR_LABEL:
 		return add_setval(ep, expr->ctype, expr);
 
+	case EXPR_FVALUE:
+		return add_setfval(ep, expr->ctype, expr->fvalue);
+
 	case EXPR_STATEMENT:
 		return linearize_statement(ep, expr->statement);
 
diff --git a/linearize.h b/linearize.h
index 7e8c0eb2c..6f4298f33 100644
--- a/linearize.h
+++ b/linearize.h
@@ -111,6 +111,9 @@ struct instruction {
 			pseudo_t symbol;		/* Subtle: same offset as "src" !! */
 			struct expression *val;
 		};
+		struct /* setfval */ {
+			long double fvalue;
+		};
 		struct /* call */ {
 			pseudo_t func;
 			union {
@@ -223,6 +226,7 @@ enum opcode {
 	OP_LOAD,
 	OP_STORE,
 	OP_SETVAL,
+	OP_SETFVAL,
 	OP_SYMADDR,
 	OP_GET_ELEMENT_PTR,
 
diff --git a/liveness.c b/liveness.c
index f7c0414b5..9a95851f8 100644
--- a/liveness.c
+++ b/liveness.c
@@ -90,6 +90,7 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction *
 		break;
 
 	case OP_SETVAL:
+	case OP_SETFVAL:
 		DEFINES(target);
 		break;
 
diff --git a/simplify.c b/simplify.c
index 256a68b22..5e3d57470 100644
--- a/simplify.c
+++ b/simplify.c
@@ -272,6 +272,7 @@ void kill_insn(struct instruction *insn, int force)
 		return;
 
 	case OP_BR:
+	case OP_SETFVAL:
 	default:
 		break;
 	}
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 415f29607..da9f2ce25 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -955,13 +955,9 @@ static void output_op_fpcast(struct function *fn, struct instruction *insn)
 static void output_op_setval(struct function *fn, struct instruction *insn)
 {
 	struct expression *val = insn->val;
-	LLVMTypeRef dtype = symbol_type(insn->type);
 	LLVMValueRef target;
 
 	switch (val->type) {
-	case EXPR_FVALUE:
-		target = LLVMConstReal(dtype, val->fvalue);
-		break;
 	case EXPR_LABEL:
 		target = LLVMBlockAddress(fn->fn, val->symbol->bb_target->priv);
 		break;
@@ -972,6 +968,15 @@ static void output_op_setval(struct function *fn, struct instruction *insn)
 	insn->target->priv = target;
 }
 
+static void output_op_setfval(struct function *fn, struct instruction *insn)
+{
+	LLVMTypeRef dtype = symbol_type(insn->type);
+	LLVMValueRef target;
+
+	target = LLVMConstReal(dtype, insn->fvalue);
+	insn->target->priv = target;
+}
+
 static void output_insn(struct function *fn, struct instruction *insn)
 {
 	switch (insn->opcode) {
@@ -990,6 +995,9 @@ static void output_insn(struct function *fn, struct instruction *insn)
 	case OP_SETVAL:
 		output_op_setval(fn, insn);
 		break;
+	case OP_SETFVAL:
+		output_op_setfval(fn, insn);
+		break;
 	case OP_SWITCH:
 		output_op_switch(fn, insn);
 		break;
diff --git a/validation/cast-constant-to-float.c b/validation/cast-constant-to-float.c
index 86b7ac0f7..ef7892f17 100644
--- a/validation/cast-constant-to-float.c
+++ b/validation/cast-constant-to-float.c
@@ -13,21 +13,21 @@ double f3(void) { return -1.0; }
 f1:
 .L0:
 	<entry-point>
-	set.64      %r1 <- -1.000000
+	setfval.64  %r1 <- -1.000000
 	ret.64      %r1
 
 
 f2:
 .L2:
 	<entry-point>
-	set.64      %r3 <- -1.000000
+	setfval.64  %r3 <- -1.000000
 	ret.64      %r3
 
 
 f3:
 .L4:
 	<entry-point>
-	set.64      %r5 <- -1.000000
+	setfval.64  %r5 <- -1.000000
 	ret.64      %r5
 
 
diff --git a/validation/cast-constants.c b/validation/cast-constants.c
index f47d6fd34..9e2006724 100644
--- a/validation/cast-constants.c
+++ b/validation/cast-constants.c
@@ -286,70 +286,70 @@ vptr_2_iptr:
 int_2_float:
 .L76:
 	<entry-point>
-	set.32      %r39 <- 123.000000
+	setfval.32  %r39 <- 123.000000
 	ret.32      %r39
 
 
 uint_2_float:
 .L78:
 	<entry-point>
-	set.32      %r41 <- 123.000000
+	setfval.32  %r41 <- 123.000000
 	ret.32      %r41
 
 
 long_2_float:
 .L80:
 	<entry-point>
-	set.32      %r43 <- 123.000000
+	setfval.32  %r43 <- 123.000000
 	ret.32      %r43
 
 
 ulong_2_float:
 .L82:
 	<entry-point>
-	set.32      %r45 <- 123.000000
+	setfval.32  %r45 <- 123.000000
 	ret.32      %r45
 
 
 double_2_float:
 .L84:
 	<entry-point>
-	set.32      %r47 <- 1.123000
+	setfval.32  %r47 <- 1.123000
 	ret.32      %r47
 
 
 int_2_double:
 .L86:
 	<entry-point>
-	set.64      %r49 <- 123.000000
+	setfval.64  %r49 <- 123.000000
 	ret.64      %r49
 
 
 uint_2_double:
 .L88:
 	<entry-point>
-	set.64      %r51 <- 123.000000
+	setfval.64  %r51 <- 123.000000
 	ret.64      %r51
 
 
 long_2_double:
 .L90:
 	<entry-point>
-	set.64      %r53 <- 123.000000
+	setfval.64  %r53 <- 123.000000
 	ret.64      %r53
 
 
 ulong_2_double:
 .L92:
 	<entry-point>
-	set.64      %r55 <- 123.000000
+	setfval.64  %r55 <- 123.000000
 	ret.64      %r55
 
 
 float_2_double:
 .L94:
 	<entry-point>
-	set.64      %r57 <- 1.123000
+	setfval.64  %r57 <- 1.123000
 	ret.64      %r57
 
 
diff --git a/validation/fp-ops.c b/validation/fp-ops.c
index 7f58a72fc..14bb12462 100644
--- a/validation/fp-ops.c
+++ b/validation/fp-ops.c
@@ -48,7 +48,7 @@ fneg:
 ftst:
 .L10:
 	<entry-point>
-	set.64      %r21 <- 0.000000
+	setfval.64  %r21 <- 0.000000
 	fcmpoeq.1   %r23 <- %arg1, %r21
 	ret.1       %r23
 
diff --git a/validation/optim/bool-context-fp.c b/validation/optim/bool-context-fp.c
new file mode 100644
index 000000000..ad075c56e
--- /dev/null
+++ b/validation/optim/bool-context-fp.c
@@ -0,0 +1,47 @@
+#define	bool	_Bool
+
+bool bfimp(float a) { return a; }
+bool bfexp(float a) { return (bool)a; }
+
+bool bfnot(float a) { return !a; }
+int  ifnot(float a) { return !a; }
+
+/*
+ * check-name: bool context fp
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-start
+bfimp:
+.L0:
+	<entry-point>
+	setfval.32  %r2 <- 0.000000
+	fcmpune.1   %r3 <- %arg1, %r2
+	ret.1       %r3
+
+
+bfexp:
+.L2:
+	<entry-point>
+	setfval.32  %r6 <- 0.000000
+	fcmpune.1   %r7 <- %arg1, %r6
+	ret.1       %r7
+
+
+bfnot:
+.L4:
+	<entry-point>
+	setfval.32  %r10 <- 0.000000
+	fcmpoeq.1   %r12 <- %arg1, %r10
+	ret.1       %r12
+
+
+ifnot:
+.L6:
+	<entry-point>
+	setfval.32  %r15 <- 0.000000
+	fcmpoeq.32  %r16 <- %arg1, %r15
+	ret.32      %r16
+
+
+ * check-output-end
+ */
-- 
2.12.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] CSE: support CSE of floating-point literal
  2017-04-12  9:29 [PATCH 0/2] floating-point literals Luc Van Oostenryck
  2017-04-12  9:29 ` [PATCH 1/2] add OP_SETFVAL Luc Van Oostenryck
@ 2017-04-12  9:29 ` Luc Van Oostenryck
  1 sibling, 0 replies; 3+ messages in thread
From: Luc Van Oostenryck @ 2017-04-12  9:29 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Before the introduction of OP_SETFVAL, floating-point were
created via OP_SETVAL whose CSE is done by comparing the
pointer of the corresponding expression without any
interpretation of this pointer.
As consequence, even if two OP_SETVAL have two identical
expressions (value), in most cases the corresponding pointers
are not identical, completly inhibiting the CSE of OP_SETVALs.

Fix the CSE of floating-point literals by directly using
the value given by the new OP_SETFVAL.

Note: to respect some of the subtilities of floating-point,
the equality comparison of two literals is not done on
the floating-point value itself but bit-by-bit on its
binary representation (as such we can continue to make the
distinction between +0.0 & -0.0, handle NaNs, ...).

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 cse.c                          | 11 +++++++++++
 validation/optim/cse-setfval.c | 12 ++++++++++++
 2 files changed, 23 insertions(+)
 create mode 100644 validation/optim/cse-setfval.c

diff --git a/cse.c b/cse.c
index f535636b4..cd1e8942c 100644
--- a/cse.c
+++ b/cse.c
@@ -89,6 +89,10 @@ static void clean_up_one_instruction(struct basic_block *bb, struct instruction
 		hash += hashval(insn->val);
 		break;
 
+	case OP_SETFVAL:
+		hash += hashval(insn->fvalue);
+		break;
+
 	case OP_SYMADDR:
 		hash += hashval(insn->symbol);
 		break;
@@ -178,6 +182,7 @@ static int insn_compare(const void *_i1, const void *_i2)
 {
 	const struct instruction *i1 = _i1;
 	const struct instruction *i2 = _i2;
+	int diff;
 
 	if (i1->opcode != i2->opcode)
 		return i1->opcode < i2->opcode ? -1 : 1;
@@ -240,6 +245,12 @@ static int insn_compare(const void *_i1, const void *_i2)
 			return i1->val < i2->val ? -1 : 1;
 		break;
 
+	case OP_SETFVAL:
+		diff = memcmp(&i1->fvalue, &i2->fvalue, sizeof(i1->fvalue));
+		if (diff)
+			return diff;
+		break;
+
 	/* Other */
 	case OP_PHI:
 		return phi_list_compare(i1->phi_list, i2->phi_list);
diff --git a/validation/optim/cse-setfval.c b/validation/optim/cse-setfval.c
new file mode 100644
index 000000000..59c00a407
--- /dev/null
+++ b/validation/optim/cse-setfval.c
@@ -0,0 +1,12 @@
+int ftest(double a, double b)
+{
+	return a == 0.125 || b == 0.125;
+}
+
+/*
+ * check-name: CSE OP_SETFVAL
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-ignore
+ * check-output-pattern-1-times: setfval\\.
+ */
-- 
2.12.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-04-12  9:31 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-12  9:29 [PATCH 0/2] floating-point literals Luc Van Oostenryck
2017-04-12  9:29 ` [PATCH 1/2] add OP_SETFVAL Luc Van Oostenryck
2017-04-12  9:29 ` [PATCH 2/2] CSE: support CSE of floating-point literal Luc Van Oostenryck

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.