Skip to content

Commit

Permalink
cl/llvm: xor, bool assign
Browse files Browse the repository at this point in the history
  • Loading branch information
versokova authored and kdudka committed Nov 27, 2015
1 parent 0954c67 commit 9cbc981
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 6 deletions.
70 changes: 65 additions & 5 deletions cl/llvm/clplug.cc
Expand Up @@ -1369,6 +1369,7 @@ void CLPass::handleBranchInstruction(BranchInst *I) {

if (I->isConditional()) {

bool insert;
struct cl_operand src;
handleOperand(I->getCondition(), &src);

Expand All @@ -1386,7 +1387,7 @@ void CLPass::handleBranchInstruction(BranchInst *I) {

//then
bb = I->getSuccessor(0);
testPhi(I->getParent(), bb);
insert = testPhi(I->getParent(), bb);
if (!bb->hasName()) {
bbName1 = "<label"+ std::to_string(bbUID++) +">";
bb->setName(bbName1);
Expand All @@ -1396,7 +1397,7 @@ void CLPass::handleBranchInstruction(BranchInst *I) {
i.data.insn_cond.then_label = bbName1.c_str(); // LABEL NAME
//else
bb = I->getSuccessor(1);
testPhi(I->getParent(), bb);
insert |= testPhi(I->getParent(), bb);
if (!bb->hasName()) {
bbName2 = "<label"+ std::to_string(bbUID++) +">";
bb->setName(bbName2);
Expand All @@ -1405,6 +1406,8 @@ void CLPass::handleBranchInstruction(BranchInst *I) {
}
i.data.insn_cond.else_label = bbName2.c_str(); // LABEL NAME

testCompareInst(I->getCondition(), insert, &src);

} else {
// unconditional
bb = I->getSuccessor(0);
Expand All @@ -1425,15 +1428,50 @@ void CLPass::handleBranchInstruction(BranchInst *I) {
cl->insn(cl, &i);
}

/// before conditional jump must be compare instruction
/// support for bool assign
/// @param cond result of compare instruction
void CLPass::testCompareInst(Value *v, bool insert, struct cl_operand *cond) {

if (isa<CmpInst>(v) && !insert)
return;

// cmp = CL_BINOP_NE: cond != falseOp
struct cl_insn i;
i.code = CL_INSN_BINOP;
findLocation(cast<Instruction>(v), &i.loc);

struct cl_operand cmp, falseOp;

// FALSE constant
falseOp.code = CL_OPERAND_CST;
falseOp.scope = CL_SCOPE_GLOBAL;
falseOp.type = cond->type;
falseOp.accessor = nullptr;
falseOp.data.cst.code = CL_TYPE_INT;
falseOp.data.cst.data.cst_int.value = 0;

cmp = *cond;
cmp.data.var = handleVariable(nullptr); // register

i.data.insn_binop.code = CL_BINOP_NE;
i.data.insn_binop.dst = &cmp;
i.data.insn_binop.src1 = cond;
i.data.insn_binop.src2 = &falseOp;
cl->insn(cl, &i);

*cond = cmp;
}

/// test, if instruction in next BasicBlock is phi
/// if yes, into BasicBlock (fromBB, witch called this function) added assign instruction
/// with value for fromBB
void CLPass::testPhi(BasicBlock *fromBB, BasicBlock *phiBB) {
bool CLPass::testPhi(BasicBlock *fromBB, BasicBlock *phiBB) {

Instruction *I = phiBB->begin();
// errs() << "is phi? " << *I << "\n";
if (!isa<PHINode>(I)) {
return;
return false;
}

struct cl_insn i;
Expand All @@ -1448,6 +1486,7 @@ void CLPass::testPhi(BasicBlock *fromBB, BasicBlock *phiBB) {
i.data.insn_unop.src = &src;

cl->insn(cl, &i);
return true;
}

/// decomposition of C ternar operand ()?:
Expand Down Expand Up @@ -1568,8 +1607,29 @@ void CLPass::handleBinInstruction(Instruction *I) {
i.data.insn_binop.dst = &dst;
i.data.insn_binop.src1 = &src1;
i.data.insn_binop.src2 = &src2;
cl->insn(cl, &i);

if (src1.type->code == CL_TYPE_BOOL &&
src2.type->code == CL_TYPE_BOOL) {

switch(I->getOpcode()) {
case Instruction::And:
i.data.insn_binop.code = CL_BINOP_TRUTH_AND;
break;

case Instruction::Or:
i.data.insn_binop.code = CL_BINOP_TRUTH_OR;
break;

case Instruction::Xor:
i.data.insn_binop.code = CL_BINOP_TRUTH_XOR;
break;

default:
break;
}
}

cl->insn(cl, &i);
}

/// what kind of compare instruction it's
Expand Down
3 changes: 2 additions & 1 deletion cl/llvm/clplug.hh
Expand Up @@ -156,7 +156,8 @@ struct CLPass : public ModulePass {
void handleCmpInstruction(Instruction *);
enum cl_binop_e getCLCodePredic(enum CmpInst::Predicate);
void handleBranchInstruction(BranchInst *);
void testPhi(BasicBlock *, BasicBlock *);
void testCompareInst(Value *, bool, struct cl_operand *);
bool testPhi(BasicBlock *, BasicBlock *);
void handleSelectInstruction(SelectInst *);
void handleUnaryInstruction(Instruction *);
void handleCallInstruction(CallInst *);
Expand Down
39 changes: 39 additions & 0 deletions sl/symproc.cc
Expand Up @@ -2146,6 +2146,39 @@ TValId handleIntegralOp(
return sh.valCreate(VT_UNKNOWN, VO_UNKNOWN);
}

TValId handleBitXor(SymHeapCore &sh, const TValId v1, const TValId v2)
{
IR::TInt num1, num2;
if (!numFromVal(&num1, sh, v1) || !numFromVal(&num2, sh, v2))
return sh.valCreate(VT_UNKNOWN, VO_UNKNOWN);

// compute the integral result
const IR::TInt result = (num1 == -1)? ~num2
: (num2 == -1)? ~num1
: (num1 ^ num2);

// wrap the result as a heap value expressing a constant integer
CustomValue cv(IR::rngFromNum(result));
return sh.valWrapCustom(cv);

}

TValId handleTruthXor(SymHeapCore &sh, const TValId v1, const TValId v2)
{
IR::TInt num1, num2;
if (!numFromVal(&num1, sh, v1) || !numFromVal(&num2, sh, v2))
return sh.valCreate(VT_UNKNOWN, VO_UNKNOWN);

// compute the integral result
const IR::TInt result = (num1 == -1)? !num2
: (num2 == -1)? !num1
: (num1 != num2);

// wrap the result as a heap value expressing a constant integer
CustomValue cv(IR::rngFromNum(result));
return sh.valWrapCustom(cv);
}

TValId handleBitNot(SymHeapCore &sh, const TValId val)
{
// check whether the value is an integral constant
Expand Down Expand Up @@ -2387,6 +2420,12 @@ struct OpHandler</* binary */ 2> {
case CL_BINOP_TRUNC_DIV:
goto handle_int;

case CL_BINOP_TRUTH_XOR:
return handleTruthXor(sh, rhs[0], rhs[1]);

case CL_BINOP_BIT_XOR:
return handleBitXor(sh, rhs[0], rhs[1]);

case CL_BINOP_BIT_AND:
if (VAL_NULL == rhs[0] || VAL_NULL == rhs[1])
// whatever we got as the second operand, the result is zero
Expand Down

0 comments on commit 9cbc981

Please sign in to comment.