コード例 #1
0
ファイル: DSWP_5.cpp プロジェクト: chengli1986/dswp
void DSWP::insertProduce(Instruction *u, Instruction *v, DType dtype, int channel, int uthread, int vthread) {
  Function *fun = module->getFunction("sync_produce");
  vector<Value *> args;
  Instruction *insPos = u->getNextNode();

  if (insPos == NULL) {
      error("here cannot be null");
  }

  //if (isa<BranchInst>(u)) {
  //	error("I don't know how do deal with it");
  //	return;
  //}

  if (dtype == REG) {	// register dep
      // cast the value to something that the communication guy likes
      CastInst *cast;

      if (u->getType()->isIntegerTy()) {
          cast = new ZExtInst(u, eleType, u->getName().str() + "_64");
      } else if (u->getType()->isFloatingPointTy()) {
          if (u->getType()->isFloatTy()) {
              cout << "WARNING: float sucks?";
          }
          cast = new BitCastInst(u, eleType, u->getName().str() + "_64");
      } else if (u->getType()->isPointerTy()){
          cast = new PtrToIntInst(u, eleType, u->getName().str() + "_64");
      } else {
          error("what's the hell type");
      }

      cast->insertBefore(insPos);
      args.push_back(cast);

      /* TODO: for true memory dependences, need to send anything or just sync?
      } else if (dtype == DTRUE) { // true dep
        error("check mem dep!!");

      StoreInst *store = dyn_cast<StoreInst>(u);
      if (store == NULL) {
        error("not true dependency!");
      }

      BitCastInst *cast = new BitCastInst(store->getOperand(0), Type::getInt8PtrTy(*context), u->getName().str() + "_ptr");
      cast->insertBefore(insPos);
      args.push_back(cast);
    */
    } else { // others
        // just send a dummy value for synchronization
        args.push_back(Constant::getNullValue(Type::getInt64Ty(*context)));
    }

    // channel ID
    args.push_back(ConstantInt::get(Type::getInt32Ty(*context), channel));

    // make the actual call
    CallInst *call = CallInst::Create(fun, args, "", insPos);
}
コード例 #2
0
void Transformer4Trace::transformPthreadCondSignal(Module* module, CallInst* call, AliasAnalysis& AA) {
    Value * val0 = call->getArgOperand(0);
    Value * val1 = call->getArgOperand(1);
    int svIdx0 = this->getValueIndex(module, val0, AA);
    int svIdx1 = this->getValueIndex(module, val1, AA);
    if (svIdx0 == -1 && svIdx1 == -1) return;

    CastInst* cond = CastInst::CreatePointerCast(val0, Type::getIntNPtrTy(module->getContext(),POINTER_BIT_SIZE));
    cond->insertBefore(call);

    CastInst* mut = CastInst::CreatePointerCast(val1, Type::getIntNPtrTy(module->getContext(),POINTER_BIT_SIZE));
    mut->insertBefore(call);

    Value* lnval = getOtInsertLineNumberValue(module, call);

    this->insertCallInstBefore(call, F_prenotify, cond, mut, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
    this->insertCallInstAfter(call, F_notify, cond, mut, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
}
コード例 #3
0
void Transformer4Trace::transformMemCpyMov(Module* module, CallInst* call, AliasAnalysis& AA) {
    Value* lnval = getOtInsertLineNumberValue(module, call);

    Value * dst = call->getArgOperand(0);
    Value * src = call->getArgOperand(1);
    int svIdx_dst = this->getValueIndex(module, dst, AA);
    int svIdx_src = this->getValueIndex(module, src, AA);
    if (svIdx_dst == -1 && svIdx_src == -1) {
        return;
    } else if (svIdx_dst != -1 && svIdx_src != -1) {
        CastInst* d = CastInst::CreatePointerCast(dst, Type::getIntNPtrTy(module->getContext(),POINTER_BIT_SIZE));
        d->insertBefore(call);

        CastInst* s = CastInst::CreatePointerCast(src, Type::getIntNPtrTy(module->getContext(),POINTER_BIT_SIZE));
        s->insertBefore(call);

        if (svIdx_dst != svIdx_src) {


            insertCallInstBefore(call, F_prestore, d, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
            insertCallInstAfter(call, F_store, d, lnval, getOrInsertSrcFileNameValue(module, call), NULL);

            insertCallInstBefore(call, F_preload, s, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
            insertCallInstAfter(call, F_load, s, lnval, getOrInsertSrcFileNameValue(module, call), NULL);

        } else {
            insertCallInstBefore(call, F_prestore, d, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
            insertCallInstAfter(call, F_store, d, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
        }

    } else if (svIdx_dst != -1) {
        CastInst* d = CastInst::CreatePointerCast(dst, Type::getIntNPtrTy(module->getContext(),POINTER_BIT_SIZE));
        d->insertBefore(call);

        insertCallInstBefore(call, F_prestore, d, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
        insertCallInstAfter(call, F_store, d, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
    } else {
        CastInst* s = CastInst::CreatePointerCast(src, Type::getIntNPtrTy(module->getContext(),POINTER_BIT_SIZE));
        s->insertBefore(call);

        insertCallInstBefore(call, F_preload, s, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
        insertCallInstAfter(call, F_load, s, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
    }
}
コード例 #4
0
void Transformer4Trace::transformLoadInst(Module* module, LoadInst* inst, AliasAnalysis& AA) {
    Value * val = inst->getOperand(0);
    int svIdx = this->getValueIndex(module, val, AA);
    if (svIdx == -1) return;

    CastInst* c = CastInst::CreatePointerCast(val, Type::getIntNPtrTy(module->getContext(),POINTER_BIT_SIZE));
    c->insertBefore(inst);
    Value* lnval = getOtInsertLineNumberValue(module, inst);

    this->insertCallInstBefore(inst, F_preload, c, lnval, getOrInsertSrcFileNameValue(module, inst), NULL);
    this->insertCallInstAfter(inst, F_load, c, lnval, getOrInsertSrcFileNameValue(module, inst), NULL);
}
コード例 #5
0
void Transformer4Trace::transformMemSet(Module* module, CallInst* call, AliasAnalysis& AA) {
    Value* lnval = getOtInsertLineNumberValue(module, call);

    Value * val = call->getArgOperand(0);
    int svIdx = this->getValueIndex(module, val, AA);
    if (svIdx == -1) return;

    CastInst* c = CastInst::CreatePointerCast(val, Type::getIntNPtrTy(module->getContext(),POINTER_BIT_SIZE));
    c->insertBefore(call);

    insertCallInstBefore(call, F_prestore, c, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
    insertCallInstAfter(call, F_store, c, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
}
コード例 #6
0
void Transformer4Trace::transformOtherFunctionCalls(Module* module, CallInst* call, AliasAnalysis& AA) {
    Value* lnval = getOtInsertLineNumberValue(module, call);

    for (unsigned i = 0; i < call->getNumArgOperands(); i++) {
        Value * arg = call->getArgOperand(i);

        CastInst* c = NULL;
        if (arg->getType()->isPointerTy()) {
            c = CastInst::CreatePointerCast(arg, Type::getIntNPtrTy(module->getContext(),POINTER_BIT_SIZE));
            c->insertBefore(call);
        } else {
            continue;
        }

        int svIdx = this->getValueIndex(module, arg, AA);
        if (svIdx != -1) {
            insertCallInstBefore(call, F_prestore, c, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
            insertCallInstBefore(call, F_store, c, lnval, getOrInsertSrcFileNameValue(module, call), NULL);
        }
    }
}
コード例 #7
0
/**
 * Inserts an argument.
 * @param rw_newInstr rewrite rule - new instruction
 * @param I instruction
 * @param CalleeF function to be called
 * @param variables map of found parameters from config
 * @param where position of the placement of the new instruction
 * @return a vector of arguments for the call that is to be inserted
 *         and a pointer to the instruction after/before the new call
 *         is going to be inserted (it is either I or some newly added
 *         argument)
 */
tuple<vector<Value *>, Instruction*> InsertArgument(InstrumentInstruction rw_newInstr, Instruction *I,
                                                    Function* CalleeF, const map <string, Value*>& variables, InstrumentPlacement where) {
	std::vector<Value *> args;
	unsigned i = 0;
	Instruction* nI = I;
	for (const string& arg : rw_newInstr.parameters) {

		if (i == rw_newInstr.parameters.size() - 1) {
			break;
		}

		auto var = variables.find(arg);
		if (var == variables.end()) {
			// NOTE: in future think also about other types than ConstantInt
			int argInt;
			try {
				argInt = stoi(arg);
				LLVMContext &Context = getGlobalContext();
				Value *intValue = ConstantInt::get(Type::getInt32Ty(Context), argInt);
				args.push_back(intValue);
			} catch (invalid_argument) {
				logger.write_error("Problem with instruction arguments: invalid argument.");
			} catch (out_of_range) {
				logger.write_error("Problem with instruction arguments: out of range.");
			}
		} else {
			unsigned argIndex = 0;
			for (Function::ArgumentListType::iterator sit=CalleeF->getArgumentList().begin(); sit != CalleeF->getArgumentList().end(); ++sit) {
				Value *argV = &*sit;

				if (i == argIndex) {
					if (argV->getType() != var->second->getType()) {
						//TODO other types?
						if (!var->second->getType()->isPtrOrPtrVectorTy() && !var->second->getType()->isIntegerTy()) {
							args.push_back(var->second);
						} else {
							CastInst *CastI;
							if (var->second->getType()->isPtrOrPtrVectorTy()) {
								CastI = CastInst::CreatePointerCast(var->second, argV->getType());
							} else {
								CastI = CastInst::CreateIntegerCast(var->second, argV->getType(), true); //TODO do something about signed argument
							}

							if (Instruction *Inst = dyn_cast<Instruction>(var->second))
								CloneMetadata(Inst, CastI);

							if (where == InstrumentPlacement::BEFORE) {
								// we want to insert before I, that is:
								// %c = cast ...
								// newInstr
								// I
								//
								// NOTE that we do not set nI in this case,
								// so that the new instruction that we will insert
								// is inserted before I (and after all arguments
								// we added here)
								CastI->insertBefore(I);
							} else {
								// we want to insert after I, that is:
								// I
								// %c = cast ...
								// newInstr
								//
								// --> we must update the nI, so that the new
								// instruction is inserted after the arguments
								CastI->insertAfter(I);
								nI = CastI;
							}
							args.push_back(CastI);
						}
					} else{
						args.push_back(var->second);
					}
					break;
				}

				argIndex++;
			}
		}

		i++;
	}
	return make_tuple(args,nI);
}
コード例 #8
0
ファイル: DSWP_5.cpp プロジェクト: chengli1986/dswp
void DSWP::insertConsume(Instruction *u, Instruction *v, DType dtype, int channel, int uthread, int vthread) {
  Instruction *oldu = dyn_cast<Instruction>(newToOld[u]);
  Instruction *insPos = placeEquivalents[vthread][oldu];
  if (insPos == NULL) {
      insPos = dyn_cast<Instruction>(instMap[vthread][oldu]);
      if (insPos == NULL) {
          error("can't insert nowhere");
      }
  }

  // call sync_consume(channel)
  Function *fun = module->getFunction("sync_consume");
  vector<Value *> args;
  args.push_back(ConstantInt::get(Type::getInt32Ty(*context), channel));
  CallInst *call = CallInst::Create(fun, args, "c" + itoa(channel), insPos);

  if (dtype == REG) {
      CastInst *cast;
      string name = call->getName().str() + "_val";

      if (u->getType()->isIntegerTy()) {
          cast = new TruncInst(call, u->getType(), name);
      }
      else if (u->getType()->isFloatingPointTy()) {
          if (u->getType()->isFloatTy())
              error("cannot deal with double");
          cast = new BitCastInst(call, u->getType(), name);
      }
      else if (u->getType()->isPointerTy()){
          cast = new IntToPtrInst(call, u->getType(), name);
      } else {
          error("what's the hell type");
      }

      cast->insertBefore(insPos);

      // replace the uses
      for (Instruction::use_iterator ui = oldu->use_begin(), ue = oldu->use_end(); ui != ue; ++ui) {
          Instruction *user = dyn_cast<Instruction>(*ui);
          if (user == NULL) {
              error("used by a non-instruction?");
          }
          // make sure it's in the same function...
          if (user->getParent()->getParent() != v->getParent()->getParent()) {
              continue;
          }

          // call replaceUses so that it handles phi nodes
          map<Value *, Value *> reps;
          reps[oldu] = cast;
          replaceUses(user, reps);
      }
  } /* TODO: need to handle true memory dependences more than just syncing?
  else if (dtype == DTRUE) {	//READ after WRITE
      error("check mem dep!!");

      if (!isa<LoadInst>(v)) {
          error("not true dependency");
      }
      BitCastInst *cast = new BitCastInst(call, v->getType(), call->getName().str() + "_ptr");
      cast->insertBefore(v);

      // replace the v with 'cast' in v's thread:
      // (other thread with be dealed using dependence)
      for (Instruction::use_iterator ui = v->use_begin(), ue = v->use_end(); ui != ue; ui++) {
          Instruction *user = dyn_cast<Instruction>(*ui);

          if (user == NULL) {
            error("how could it be NULL");
          }

          //	int userthread = this->getNewInstAssigned(user);
          if (user->getParent()->getParent() != v->getParent()->getParent()) {
              continue;
          }

          for (unsigned i = 0; i < user->getNumOperands(); i++) {
              Value * op = user->getOperand(i);
	      if (op == v) {
                  user->setOperand(i, cast);
	      }
          }
      }
  } */ else {
      // nothing to do
  }
}
コード例 #9
0
ファイル: partition2.cpp プロジェクト: lihuang916/DSWP
bool partition::runOnLoop(Loop* L, LPPassManager &LPM) {
    
    errs() << "***************************  Loop encountered: ************************" << '\n' << L->getHeader()->getName() << '\n';
    
    if (function->getName() != "main")
        return false;


    IntegerType* int32Ty = Type::getInt32Ty(*context);
    IntegerType* int64Ty = Type::getInt64Ty(*context);
    PointerType* voidPtrTy = Type::getInt8PtrTy(*context);

    FunctionType* funcTy = FunctionType::get(int32Ty, false);
   
    Constant* func1_c;
    Function* func1;

    func1_c = module->getOrInsertFunction("func1", funcTy);
    func1 = cast<Function>(func1_c);


    Function* pro = module->getFunction("produce");
    Function* con = module->getFunction("consume");
    
    BasicBlock* func1EntryBlock = BasicBlock::Create(*context, "entry.func1", func1);
    AllocaInst* i_var = new AllocaInst(int32Ty, NULL, 4, "i", func1EntryBlock);
    
    Value* liveIn;
    BasicBlock *forCond, *forBody, *forInc;
    ValueToValueMapTy VMap;
    std::map<BasicBlock *, BasicBlock *> BlockMap;
    
    for (Loop::block_iterator BB = L->block_begin(), BBe = L->block_end(); BB != BBe; ++BB) {
        BasicBlock* func1Block = CloneBasicBlock(*BB, VMap, ".func1", func1);
        BlockMap[*BB] = func1Block;

        if ((*BB)->getName() == "for.cond") 
            forCond = func1Block;
        if ((*BB)->getName() == "for.body") 
            forBody = func1Block;
        if ((*BB)->getName() == "for.inc") 
            forInc = func1Block;

        for (BasicBlock::iterator it = func1Block->begin(), ite = func1Block->end(); it != ite; ++it) {
            for (User::op_iterator oit = it->op_begin(), oite = it->op_end(); oit != oite; ++oit) {
                if (VMap[*oit] != NULL) {
                    *oit = VMap[*oit];
                } else {
                    Constant* cons = dyn_cast<Constant>(*oit);
                    BranchInst* br = dyn_cast<BranchInst>(it);
                    if (cons == NULL && br == NULL) {
                        liveIn = *oit;
                        *oit = i_var;
                    }
                }
               
            }
        }

        if ((*BB)->getName() == "for.body") {
            Instruction* term = (*BB)->getTerminator();
            term->removeFromParent();
            for (int i = 0; i < 7; i++) {
                (*BB)->back().eraseFromParent();
            }
            term->insertAfter(&(*BB)->back());
            (*BB)->front().eraseFromParent();
            LoadInst* load = new LoadInst(liveIn, "", false, 4, term); 

            std::vector<Value *> produce_args;
            CastInst* cast = CastInst::CreateIntegerCast(load, int64Ty, true);
            cast->insertAfter(load);
            produce_args.push_back(cast);
            ConstantInt* val = ConstantInt::get(int32Ty, (uint32_t) 3);
            produce_args.push_back(val);
            CallInst::Create(pro, ArrayRef<Value*>(produce_args), "", term);

            produce_args.pop_back();
            val = ConstantInt::get(int32Ty, (uint32_t) 2);
            produce_args.push_back(val);
            CallInst::Create(pro, ArrayRef<Value*>(produce_args), "", term);
        }
    
    }

    // set branch instructions to restructure the CFG in created function
    BasicBlock* func1EndBlock = BasicBlock::Create(*context, "if.end.func1", func1); 
    BasicBlock* garbageBB = BasicBlock::Create(*context, "garbage", func1);
    ConstantInt* retVal_g = ConstantInt::get(int32Ty, (uint32_t) 0);
    ReturnInst* ret_g = ReturnInst::Create(*context, retVal_g, garbageBB);

    
    for (Function::iterator fit = func1->begin(), fite = func1->end(); fit != fite; ++fit) {
        if (fit->getTerminator() == NULL || fit->getName() == "garbage")
            continue;
      
        BranchInst* br = dyn_cast<BranchInst>(fit->getTerminator());
        int numSuccessors = br->getNumSuccessors();
        
        for (int i = 0; i < numSuccessors; i++) {
            BasicBlock* successor = br->getSuccessor(i);
            
            if (BlockMap[successor] != NULL) {
                
                br->setSuccessor(i, BlockMap[successor]);
            } 
            else {
                br->setSuccessor(i, func1EndBlock);
            }
            
        }
/*
        if (fit->getName() == "for.body.func1") {
            for (int i = 0; i < 4; i++) {
                BasicBlock::iterator it = fit->begin();
                it->moveBefore(ret_g);
            }
        }
        */
    }
    garbageBB->eraseFromParent();

    BranchInst* br = dyn_cast<BranchInst>(forBody->getTerminator());
    br->setSuccessor(0, forCond);
    forInc->eraseFromParent();


    // Create return instruction for func1EndBlock and set a branch from loop header to func1EndBlock
    ConstantInt* retVal = ConstantInt::get(int32Ty, (uint32_t) 0);
    ReturnInst* ret1 = ReturnInst::Create(*context, retVal, func1EndBlock);
    BasicBlock* loopHeader = BlockMap.at(L->getHeader());
    BranchInst* brInst = BranchInst::Create(loopHeader, func1EntryBlock);
    
    // add produce function call
    std::vector<Value *> produce_args;
    ConstantInt* val = ConstantInt::get(int64Ty, (uint64_t) 0);
    produce_args.push_back(val);
    val = ConstantInt::get(int32Ty, (uint32_t) 5);
    produce_args.push_back(val);
    CallInst::Create(pro, ArrayRef<Value*>(produce_args), "", func1EndBlock->getTerminator());
    
    // add consume function call
    int q_id = 2;
    for (Value::use_iterator uit = i_var->use_begin(), uite = i_var->use_end(); uit != uite; ++uit) {
        std::vector<Value *> consume_args;
        ConstantInt* val = ConstantInt::get(int32Ty, (uint32_t) q_id); 
        consume_args.push_back(val);
        CallInst* call = CallInst::Create(con, ArrayRef<Value*>(consume_args));
        Instruction* inst = dyn_cast<Instruction>(*uit);
        call->insertAfter(inst);
        CastInst* cast = CastInst::CreateIntegerCast(call, int32Ty, true);
        cast->insertAfter(call);
        (*uit)->replaceAllUsesWith(cast);
        inst->eraseFromParent();
        q_id++;
    }

    i_var->eraseFromParent();

    // add produce and consume function calls to main thread
    // transmit the function pointer to created function by a produce call
    BasicBlock* loopPreheader = L->getLoopPreheader();
    produce_args.clear();
    CastInst* cast = CastInst::CreatePointerCast(func1, int64Ty);
    cast->insertBefore(loopPreheader->getTerminator());
    produce_args.push_back(cast);
    val = ConstantInt::get(int32Ty, (uint32_t) 0);
    produce_args.push_back(val);
    CallInst::Create(pro, ArrayRef<Value*>(produce_args), "", loopPreheader->getTerminator());
  
    // transmit induction variable to created function by a produce call
    Instruction* load = &L->getHeader()->front();
    produce_args.clear();
    cast = CastInst::CreateIntegerCast(load, int64Ty, true);
    cast->insertAfter(load);
    produce_args.push_back(cast);
    val = ConstantInt::get(int32Ty, (uint32_t) 4);
    produce_args.push_back(val);
    CallInst::Create(pro, ArrayRef<Value*>(produce_args))->insertAfter(cast);



    return true;
}