Skip to content

Commit

Permalink
Merge pull request #77 from omegahm/stupid-math
Browse files Browse the repository at this point in the history
Stupid math
  • Loading branch information
madsbk committed Apr 6, 2016
2 parents 05691d8 + b626c86 commit b6b82fb
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 7 deletions.
5 changes: 3 additions & 2 deletions config.ini.in
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,9 @@ children = node
type = filter
impl = ${CMAKE_INSTALL_PREFIX}/lib/libbh_filter_bccon${CMAKE_SHARED_LIBRARY_SUFFIX}
children = node
reduction = 1
collect = 1
reduction = true
collect = true
stupidmath = true
timing = false

[noneremover]
Expand Down
13 changes: 8 additions & 5 deletions filter/bccon/component_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ If not, see <http://www.gnu.org/licenses/>.
#include "component_interface.h"
#include "reduction_chain_filter.hpp"
#include "collect_filter.hpp"
#include "stupid_math_filter.hpp"

//
// Components
Expand All @@ -35,7 +36,7 @@ static bh_component myself; // Myself
// Function pointers to our child.
static bh_component_iface *child;

static bool reduction_, collect_;
static bool reduction_, stupidmath_, collect_;

// The timing ID for the filter
static bh_intp exec_timing;
Expand Down Expand Up @@ -68,8 +69,9 @@ bh_error bh_filter_bccon_init(const char* name)
return err;
}

reduction_ = bh_component_config_lookup_bool(&myself, "reduction", false);
collect_ = bh_component_config_lookup_bool(&myself, "collect", false);
reduction_ = bh_component_config_lookup_bool(&myself, "reduction", false);
stupidmath_ = bh_component_config_lookup_bool(&myself, "stupidmath", false);
collect_ = bh_component_config_lookup_bool(&myself, "collect", false);

return BH_SUCCESS;
}
Expand All @@ -94,8 +96,9 @@ bh_error bh_filter_bccon_execute(bh_ir* bhir)
if (timing)
start = bh_timer_stamp();

if (reduction_) reduction_chain_filter(*bhir);
if (collect_) collect_filter(*bhir);
if (reduction_) reduction_chain_filter(*bhir);
if (stupidmath_) stupid_math_filter(*bhir);
if (collect_) collect_filter(*bhir);

if (timing)
bh_timer_add(exec_timing, start, bh_timer_stamp());
Expand Down
165 changes: 165 additions & 0 deletions filter/bccon/stupid_math_filter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.
Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.
Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the
GNU Lesser General Public License along with Bohrium.
If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <set>

#include <bh_component.h>
#include <bh.h>

using namespace std;

bool bh_constant_is_value(bh_constant constant, float_t value)
{
switch(constant.type) {
case BH_UINT8:
return constant.value.uint8 == (uint8_t)value;
case BH_UINT16:
return constant.value.uint16 == (uint16_t)value;
case BH_UINT32:
return constant.value.uint32 == (uint32_t)value;
case BH_UINT64:
return constant.value.uint64 == (uint64_t)value;

case BH_INT8:
return constant.value.int8 == (int8_t)value;
case BH_INT16:
return constant.value.int16 == (int16_t)value;
case BH_INT32:
return constant.value.int32 == (int32_t)value;
case BH_INT64:
return constant.value.int64 == (int64_t)value;

// We can't use floating point, since we'll lose precision
/*
case BH_FLOAT32:
return constant.value.float32 == value;
case BH_FLOAT64:
return constant.value.float64 == value;
*/

default:
return false;
}
}

bool is_multiplying_by_one(bh_instruction& instr)
{
return instr.opcode == BH_MULTIPLY and
bh_is_constant(&(instr.operand[2])) and
bh_constant_is_value(instr.constant, 1.0);
}

bool is_dividing_by_one(bh_instruction& instr)
{
return instr.opcode == BH_DIVIDE and
bh_is_constant(&(instr.operand[2])) and
bh_constant_is_value(instr.constant, 1.0);
}

bool is_adding_zero(bh_instruction& instr)
{
return instr.opcode == BH_ADD and
bh_is_constant(&(instr.operand[2])) and
bh_constant_is_value(instr.constant, 0.0);
}

bool is_subtracting_zero(bh_instruction& instr)
{
return instr.opcode == BH_SUBTRACT and
bh_is_constant(&(instr.operand[2])) and
bh_constant_is_value(instr.constant, 0.0);
}

bool is_free_or_discard(bh_instruction& instr)
{
return instr.opcode == BH_FREE or
instr.opcode == BH_DISCARD;
}

bool is_doing_stupid_math(bh_instruction& instr)
{
return is_multiplying_by_one(instr) or
is_dividing_by_one(instr) or
is_adding_zero(instr) or
is_subtracting_zero(instr);
}

void stupid_math_filter(bh_ir &bhir)
{
for(size_t pc = 0; pc < bhir.instr_list.size(); ++pc) {
bh_instruction& instr = bhir.instr_list[pc];

if (is_doing_stupid_math(instr)) {
// We could have the following:
// BH_MULTIPLY B A 0
// ...
// BH_FREE A
// BH_DISCARD A

bh_base* B = instr.operand[0].base;
bh_base* A = instr.operand[1].base;

bool freed = false;
bool discarded = false;

for (size_t pc_chain = pc+1; pc_chain < bhir.instr_list.size(); ++pc_chain) {
bh_instruction& other_instr = bhir.instr_list[pc_chain];

// Look for matching FREE and DISCARD for B
if (is_free_or_discard(other_instr) and (other_instr.operand[0].base == B)) {
freed = freed or other_instr.opcode == BH_FREE;
discarded = discarded or other_instr.opcode == BH_DISCARD;
}
}

// Check that B is created by us, that is, it isn't created prior to this stupid math call.
bool created_before = false;
for (size_t pc_chain = 0; pc_chain < pc; ++pc_chain) {
bh_instruction& other_instr = bhir.instr_list[pc_chain];
for (int idx = 0; idx < bh_noperands(other_instr.opcode); ++idx) {
created_before = created_before or other_instr.operand[idx].base == B;
}
if (created_before) break;
}

// Only if we FREE and DISCARD B in the same flush, are we allowed to change things.
if (freed and discarded and !created_before) {
for (size_t pc_chain = pc+1; pc_chain < bhir.instr_list.size(); ++pc_chain) {
bh_instruction& other_instr = bhir.instr_list[pc_chain];

// Look for matching FREE and DISCARD for A
if (is_free_or_discard(other_instr) and (other_instr.operand[0].base == A)) {
other_instr.opcode = BH_NONE; // Remove instruction
}

// Rewrite all uses of B to A
for (int idx = 0; idx < bh_noperands(other_instr.opcode); ++idx) {
if (other_instr.operand[idx].base == B) {
other_instr.operand[idx].base = A;
}
}
}

// Remove self
instr.opcode = BH_NONE;
}
}
}
}
1 change: 1 addition & 0 deletions filter/bccon/stupid_math_filter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
void stupid_math_filter(bh_ir &bhir);

0 comments on commit b6b82fb

Please sign in to comment.