Example #1
1
/// RewriteUsesOfClonedInstructions - We just cloned the instructions from the
/// old header into the preheader.  If there were uses of the values produced by
/// these instruction that were outside of the loop, we have to insert PHI nodes
/// to merge the two values.  Do this now.
static void RewriteUsesOfClonedInstructions(BasicBlock *OrigHeader,
                                            BasicBlock *OrigPreheader,
                                            ValueToValueMapTy &ValueMap) {
  // Remove PHI node entries that are no longer live.
  BasicBlock::iterator I, E = OrigHeader->end();
  for (I = OrigHeader->begin(); PHINode *PN = dyn_cast<PHINode>(I); ++I)
    PN->removeIncomingValue(PN->getBasicBlockIndex(OrigPreheader));

  // Now fix up users of the instructions in OrigHeader, inserting PHI nodes
  // as necessary.
  SSAUpdater SSA;
  for (I = OrigHeader->begin(); I != E; ++I) {
    Value *OrigHeaderVal = I;

    // If there are no uses of the value (e.g. because it returns void), there
    // is nothing to rewrite.
    if (OrigHeaderVal->use_empty())
      continue;

    Value *OrigPreHeaderVal = ValueMap[OrigHeaderVal];

    // The value now exits in two versions: the initial value in the preheader
    // and the loop "next" value in the original header.
    SSA.Initialize(OrigHeaderVal->getType(), OrigHeaderVal->getName());
    SSA.AddAvailableValue(OrigHeader, OrigHeaderVal);
    SSA.AddAvailableValue(OrigPreheader, OrigPreHeaderVal);

    // Visit each use of the OrigHeader instruction.
    for (Value::use_iterator UI = OrigHeaderVal->use_begin(),
         UE = OrigHeaderVal->use_end(); UI != UE; ) {
      // Grab the use before incrementing the iterator.
      Use &U = *UI;

      // Increment the iterator before removing the use from the list.
      ++UI;

      // SSAUpdater can't handle a non-PHI use in the same block as an
      // earlier def. We can easily handle those cases manually.
      Instruction *UserInst = cast<Instruction>(U.getUser());
      if (!isa<PHINode>(UserInst)) {
        BasicBlock *UserBB = UserInst->getParent();

        // The original users in the OrigHeader are already using the
        // original definitions.
        if (UserBB == OrigHeader)
          continue;

        // Users in the OrigPreHeader need to use the value to which the
        // original definitions are mapped.
        if (UserBB == OrigPreheader) {
          U = OrigPreHeaderVal;
          continue;
        }
      }

      // Anything else can be handled by SSAUpdater.
      SSA.RewriteUse(U);
    }
  }
}
Example #2
0
void GraphEdge::print(raw_ostream &OS) {
  const StringRef MayColor = "black";
  const StringRef MustColor = "blue";

  StringRef Color;
  if (ETy == MAY) {
    Color = MayColor;
  } else if (ETy == MUST) {
    Color = MustColor;
  } else {
    assert(false && "Invalid ETy");
  }

  Value *FromValue = From->getValue();
  if (FromValue->hasName())
    OS << "    \"" << FromValue->getName();
  else
    OS << "    \"" << *FromValue;

  OS << "\" -> "; 

  Value *ToValue = To->getValue();
  if (ToValue->hasName())
    OS << "\"" << ToValue->getName();
  else
    OS << "\"" << *ToValue;

  OS << "\" [label =\"" << Weight << "\", color = \"" << Color << "\"];\n";
}
PointerAnalysisFlow* PointerAnalysis::operation_pX_Y(PointerAnalysisFlow* in, Instruction* instruction){
	PointerAnalysisFlow* f = new PointerAnalysisFlow(in);
	Value* Y = instruction->getOperand(0); //RO
	Value* X = instruction->getNextNode()->getOperand(0); //LO
	//Check that both operands are pointers.
	if (Y->getType()->isPointerTy() && X->getType()->isPointerTy()) {
		if (Y->getName()!="" && X->getName()!="") {
			//Everything Y points to, *X points to now as well.
			//*X points to Y points to 
			PointerAnalysisFlow* ff = new PointerAnalysisFlow();
			set<string> pointedByX = in->value[X->getName()];
			map<string, set<string> > value;
			for (set<string>::iterator it = pointedByX.begin() ; it != pointedByX.end() ; it++) {

				string x = *it;
				value[x] = in->value[Y->getName()];
			}
			ff->value = value;
			PointerAnalysisFlow* tmp = static_cast<PointerAnalysisFlow*>(ff->join(f));
			delete ff;
			delete f;
			f = tmp;
		}
	}
	return f;
}
Example #4
0
// =============================================================================
// dump
// 
// Dump the expression maps
// =============================================================================
void Context::dump() {
    std::cout << "-------" << std::endl;
    val2expr_map::iterator it;
    for (it = val2expr.begin (); it != val2expr.end (); ++it) {
        Value *key = (*it).first;
        ExprPtr var = (*it).second;
        std::cout << "name = " << key->getName().str() 
        << "  expr = " << var << std::endl;
    }
    val2expr_map::iterator it2;
    for (it2 = val2num.begin (); it2 != val2num.end (); ++it2) {
        Value *key = (*it2).first;
        ExprPtr var = (*it2).second;
        if(ConstantInt *ci = dyn_cast<ConstantInt>(key)) {
            int val = (int) ci->getSExtValue();
            std::cout << "num = " << val
            << "  expr = " << var << std::endl;
        }
    }
    val2expr_map::iterator it3;
    for (it3 = val2lbl.begin (); it3 != val2lbl.end (); ++it3) {
        Value *key = (*it3).first;
        ExprPtr var = (*it3).second;
        std::cout << "label = " << key->getName().str()
        << "  expr = " << var << std::endl;        
    }
    
    std::cout << "-------" << std::endl;
}
/*
 * Find stores to arguments that are not read on the caller function. If the
 * corresponding actual argument is locally declared on the caller, the
 * store can be removed with cloning.
 */
void DeadStoreEliminationPass::runNotUsedDeadStoreAnalysis() {

  DEBUG(errs() << "Running not used dead store analysis...\n");
  for(std::map<Function*, std::set<Value*> >::iterator it =
        fnThatStoreOnArgs.begin(); it != fnThatStoreOnArgs.end(); ++it) {
    Function* F = it->first;
    DEBUG(errs() << "  Verifying function " << F->getName() << ".\n");

    // Verify each callsite of functions that store on arguments
    for (Value::use_iterator UI = F->use_begin(), E = F->use_end();
          UI != E; ++UI) {
       User *U = *UI;

      if (isa<BlockAddress>(U)) continue;
      if (!isa<CallInst>(U) && !isa<InvokeInst>(U)) continue;

      Instruction* inst = cast<Instruction>(U);
      if (deadArguments.count(inst)) continue;

      CallSite CS(inst);
      if (!CS.isCallee(UI)) continue;

      CallSite::arg_iterator actualArgIter = CS.arg_begin();
      Function::arg_iterator formalArgIter = F->arg_begin();
      int size = F->arg_size();

      std::set<Value*> storedArgs = fnThatStoreOnArgs[F];
      for (int i = 0; i < size; ++i, ++actualArgIter, ++formalArgIter) {
        Value *formalArg = formalArgIter;
        Value *actualArg = *actualArgIter;

        if (storedArgs.count(formalArg)) {
          DEBUG(errs() << "    Store on " << formalArg->getName()
                << " may be removed with cloning on instruction " << *inst << "\n");
          //TODO: handle malloc and other allocation functions
          Instruction* argDeclaration = dyn_cast<Instruction>(actualArg);
          if (!argDeclaration || !isa<AllocaInst>(argDeclaration)) {
            DEBUG(errs() << "    Can't remove because actual arg was not locally allocated.\n");
            continue;
          }
          if (hasAddressTaken(argDeclaration, CS)) {
            DEBUG(errs() << "    Can't remove because actual arg has its address taken.\n");
            continue;
          }
          if (isRefAfterCallSite(actualArg, CS)) {
            DEBUG(errs() << "    Can't remove because actual arg is used after callSite.\n");
            continue;
          }
          DEBUG(errs() << "  Store on " << formalArg->getName() << " will be removed with cloning\n");
          deadArguments[inst].insert(formalArg);
        }
      }
      if (deadArguments.count(inst)) {
        fn2Clone[F].push_back(inst);
      }
    }
  }
  DEBUG(errs() << "\n");
}
void GlobalCheck::print() 
{
  if (isUpper) {
    errs() << "(" << var->getName() << " < " << *(bound) << ")\n";
  } else {
    errs() << "(0 < " << var->getName() << ")\n";
  }
}
Example #7
0
void Strator::StratorWorker::detectRaces(const Instruction& inst, bool isStore, LockSet& lockSet){
	string fName = inst.getParent()->getParent()->getName().str();
	AccessType* accessType = new AccessType(isStore, multithreadedFunctionMap[fName], &inst, lockSet);
	Instruction* defInst = const_cast<Instruction*>(&inst);
	Value* operand = NULL;


	if(isStore){
		assert(inst.getNumOperands() == 2 && "Store should have 2 operands");
		//operand = parent->getDefOperand(defInst, defInst->getOperand(1));
		operand = parent->getDefOperand(defInst->getOperand(1), parentValue);
	} else{
		assert(inst.getNumOperands() == 1 && "Load should have 1 operand");
		//operand = parent->getDefOperand(defInst, defInst->getOperand(0));
		operand = parent->getDefOperand(defInst->getOperand(0), parentValue);
	}

	if(operand){
		if(isa<GlobalVariable>(operand)){
			/// Ignore constant globals
			if( ((GlobalVariable*)(operand))->isConstant())
				return;
		}
		if (parent->getLocation(&inst) == "pbzip2.c: l.673"){
			cerr << "Recording access in function: " << fName << " mt: " << multithreadedFunctionMap[fName] << endl;
			cerr << "location:" << parent->getLocation(&inst) << endl;
			cerr << "Variable: " << operand->getName().str() << endl;
			cerr << "And instruction: ";
			llvm::errs() << inst;
			cerr << endl;
			cerr << "Lockset:" << endl;
			Strator::StratorWorker::LockSet::iterator it;
			for(it = lockSet.begin(); it != lockSet.end(); ++it){
				cerr << "   lock: " << *it << endl;
			}
		}
#ifdef DETAILED_DEBUG
		cerr << "Recording access in function: " << fName << " mt: " << multithreadedFunctionMap[fName] << endl;
		cerr << "location:" << parent->getLocation(&inst) << endl;
		cerr << "Variable: " << operand->getName().str() << endl;
		cerr << "And instruction: ";
		llvm::errs() << inst;
		cerr << endl;
		cerr << "Lockset:" << endl;
		Strator::StratorWorker::LockSet::iterator it;
		for(it = lockSet.begin(); it != lockSet.end(); ++it){
			cerr << "   lock: " << *it << endl;
		}
#endif
		if (!multithreadedFunctionMap[fName])
			return;
		valueToAccessTypeMap[operand]./*push_back*/insert(accessType);
	}
}
Example #8
0
bool RegisterStackPools::runOnFunction(Function &F) {
  TargetData *TD = &getAnalysis<TargetData>();
  SmallVector<Value*, 16> Objects;
  Module &M = *F.getParent();

  Function *RegisterStackPoolFunction = M.getFunction("__pool_register_stack");
  assert(RegisterStackPoolFunction &&
         "__pool_register_stack function has disappeared!\n");

  // Collect alloca instructions
  for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB)
    for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I)
      if (isa<AllocaInst>(I))
        Objects.push_back(I);

  // Collect ByVal arguments
  if (RegByval) {
    for (Function::arg_iterator Arg = F.arg_begin(), E = F.arg_end();
         Arg != E;
         ++Arg) {
      if (Arg->hasByValAttr())
        Objects.push_back(Arg);
    }
  }

  IRBuilder<> Builder(F.getContext());
  ObjectSizeOffsetEvaluator ObjSizeEval(TD, F.getContext());

  // Add the registration calls.
  for (size_t i = 0, N = Objects.size(); i < N; i++) {
    Value *V = Objects[i];

    if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
      Builder.SetInsertPoint(++BasicBlock::iterator(AI));
    } else {
      Builder.SetInsertPoint(&F.getEntryBlock().front());
    }

    SizeOffsetEvalType SizeOffset = ObjSizeEval.compute(V);
    assert(ObjSizeEval.bothKnown(SizeOffset));
    assert(dyn_cast<ConstantInt>(SizeOffset.second)->isZero());

    Value *Size = SizeOffset.first;
    Size = Builder.CreateIntCast(Size, SizeTy, false,
                                 Size->getName() + ".casted");
    Value *VoidPtr = Builder.CreatePointerCast(V, VoidPtrTy,
                                               V->getName() + ".casted");
    Builder.CreateCall2(RegisterStackPoolFunction, VoidPtr, Size);

    ++StackPoolsRegistered;
  }

  return !Objects.empty();
}
Example #9
0
/////////////////////////////////
//replaceOperands()            //
/////////////////////////////////
void InsDuplica::replaceOperands(Instruction *newI) {
   unsigned int numOP = newI->getNumOperands();
   int stride = 1;

   // for PHINode, values are on i*2 positions.
   if (isa<PHINode>(newI)) stride = 2;

   for (unsigned int i=0; i<numOP; i+=stride) {
      Value *curOP = newI->getOperand(i);

#ifdef REG_SAFE
      // If curOP is on safe reg set, we will not replace it.
      if (curSafeRegs->isValueSafe(curOP)) {
#ifdef Jing_DEBUG
         std::cerr << "safe(";
         if (newI->hasName()) std::cerr << newI->getName() <<":";
         else std::cerr << "U:";

         std::cerr << curOP->getName() <<"),";
#endif
         continue;
      }

      // For a PHINode, we will check the corresponding incoming edge.
      if (isa<PHINode>(newI)) {
         // The index for this incoming block is i/2
         if (curSafeRegs->isValueSafeonIncoming(i/2, curOP)) {
#ifdef Jing_DEBUG
            std::cerr <<"PHIsafe(I:"<<i/2<<",v:"<<curOP->getName()<<"),";
#endif
         }
         continue;
      }
#endif

      if (valueMap.count(curOP) > 0) {
         //curOP has a replica (or dummy replica)
         if (valueMap[curOP] != curOP) 
            newI->setOperand(i,valueMap[curOP]);
      } else {
         //currently curOP does not have an entry
         //we check if this curOP is duplicable, if yes then we insert a update request to toAddvalueMap
         if (Instruction *curOPI = dyn_cast<Instruction>(curOP)) {
            //if curOP is not an instruction(const or BasicBlock*), we can not duplicate it
#ifdef Jing_DEBUG
            std::cerr << "curOP does not have a copy " << curOP->getName() << " at " << newI->getName() << "\n";
#endif
            requestToMap(curOPI, newI);
         }
      } //end of if
   } //end of for
}
/*
 * Build information about functions that store on pointer arguments
 * For simplification, we only consider a function to store on an argument
 * if it has exactly one StoreInst to that argument and the arg has no other use.
 */
int DeadStoreEliminationPass::getFnThatStoreOnArgs(Module &M) {
  int numStores = 0;
  DEBUG(errs() << "Getting functions that store on arguments...\n");
  for (Module::iterator F = M.begin(); F != M.end(); ++F) {
    if (F->arg_empty() || F->isDeclaration()) continue;

    // Get args
    std::set<Value*> args;
    for (Function::arg_iterator formalArgIter = F->arg_begin();
          formalArgIter != F->arg_end(); ++formalArgIter) {
      Value *formalArg = formalArgIter;
      if (formalArg->getType()->isPointerTy()) {
        args.insert(formalArg);
      }
    }

    // Find stores on arguments
    for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) {
      for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
        Instruction *inst = I;
        if (!isa<StoreInst>(inst)) continue;
        StoreInst *SI = dyn_cast<StoreInst>(inst);
        Value *ptrOp = SI->getPointerOperand();

        if (args.count(ptrOp) && ptrOp->hasNUses(1)) {
          fnThatStoreOnArgs[F].insert(ptrOp);
          numStores++;
          DEBUG(errs() << "  " << F->getName() << " stores on argument "
                << ptrOp->getName() << "\n"); }
      }
    }
  }
  DEBUG(errs() << "\n");
  return numStores;
}
Example #11
0
std::string Naming::get(const Value& V) {

    if (names.count(&V))
        return names[&V];

    std::string name;

    if (V.hasName() && !isa<Instruction>(&V)) {
        name = escape(V.getName().str());
        if (isBplKeyword(name))
            name = name + "_";

    } else if (isa<GlobalValue>(&V)) {
        // XXX is this a problem?
        assert( false && "Unexpected unnamed global vlaue." );

    } else if (isa<BasicBlock>(&V)) {
        name = freshBlockName();

    } else if (isa<UndefValue>(&V)) {
        name = freshUndefName();

    } else if (isa<Instruction>(&V)) {
        name = freshVarName(V);

    } else if (isa<Argument>(&V)) {
        name = freshVarName(V);

    } else {
        name = "";
    }

    names[&V] = name;
    return name;
}
Example #12
0
/// Create check flag for `LD`, which is set to true if
/// the memory at `LD.getOperand(0)` is changed
/// returns the created flag address value
Value *RedoBBBuilder::createCheckFlag(LoadInst &LD)
{
    // reuse flag for the same memory address
    Value *flag = LdToFlagMap[&LD];
    if (flag) {
        DEBUG(dbgs() << "    Reuse existing flag.\n");
    } else {
        // create flag variable
        BasicBlock *prepre = pass->getOrCreatePrePreheader();
        BasicBlock *postPre = pass->getOrCreatePostPreheader();
        flag = new AllocaInst(Type::getInt1Ty(LD.getContext()),
                              LD.getName() + ".flag",
                              prepre->getTerminator());

        new StoreInst(ConstantInt::getFalse(LD.getContext()),
                    flag, postPre->getTerminator());

        LdToFlagMap[&LD] = flag;
    }

    DEBUG(dbgs() << "        Created check flag '" << flag->getName() << "' for (" << LD << "  )\n");

    // insert check to potential stores
    // insert check to all potential alias address users
    for (auto pointerRec : pass->getAliasSetForLoadSrc(&LD)) {
        insertCheck(pointerRec.getValue(), LD.getOperand(0), flag);
    }

    return flag;
}
// Generate testSetjmp function call seqence with preamble and postamble.
// The code this generates is equivalent to the following JavaScript code:
// if (%__THREW__.val != 0 & threwValue != 0) {
//   %label = _testSetjmp(mem[%__THREW__.val], setjmpTable, setjmpTableSize);
//   if (%label == 0)
//     emscripten_longjmp(%__THREW__.val, threwValue);
//   __tempRet0 = threwValue;
// } else {
//   %label = -1;
// }
// %longjmp_result = __tempRet0;
//
// As output parameters. returns %label, %longjmp_result, and the BB the last
// instruction (%longjmp_result = ...) is in.
void WebAssemblyLowerEmscriptenEHSjLj::wrapTestSetjmp(
    BasicBlock *BB, Instruction *InsertPt, Value *Threw, Value *SetjmpTable,
    Value *SetjmpTableSize, Value *&Label, Value *&LongjmpResult,
    BasicBlock *&EndBB) {
  Function *F = BB->getParent();
  LLVMContext &C = BB->getModule()->getContext();
  IRBuilder<> IRB(C);
  IRB.SetInsertPoint(InsertPt);

  // if (%__THREW__.val != 0 & threwValue != 0)
  IRB.SetInsertPoint(BB);
  BasicBlock *ThenBB1 = BasicBlock::Create(C, "if.then1", F);
  BasicBlock *ElseBB1 = BasicBlock::Create(C, "if.else1", F);
  BasicBlock *EndBB1 = BasicBlock::Create(C, "if.end", F);
  Value *ThrewCmp = IRB.CreateICmpNE(Threw, IRB.getInt32(0));
  Value *ThrewValue =
      IRB.CreateLoad(ThrewValueGV, ThrewValueGV->getName() + ".val");
  Value *ThrewValueCmp = IRB.CreateICmpNE(ThrewValue, IRB.getInt32(0));
  Value *Cmp1 = IRB.CreateAnd(ThrewCmp, ThrewValueCmp, "cmp1");
  IRB.CreateCondBr(Cmp1, ThenBB1, ElseBB1);

  // %label = _testSetjmp(mem[%__THREW__.val], _setjmpTable, _setjmpTableSize);
  // if (%label == 0)
  IRB.SetInsertPoint(ThenBB1);
  BasicBlock *ThenBB2 = BasicBlock::Create(C, "if.then2", F);
  BasicBlock *EndBB2 = BasicBlock::Create(C, "if.end2", F);
  Value *ThrewInt = IRB.CreateIntToPtr(Threw, Type::getInt32PtrTy(C),
                                       Threw->getName() + ".i32p");
  Value *LoadedThrew =
      IRB.CreateLoad(ThrewInt, ThrewInt->getName() + ".loaded");
  Value *ThenLabel = IRB.CreateCall(
      TestSetjmpF, {LoadedThrew, SetjmpTable, SetjmpTableSize}, "label");
  Value *Cmp2 = IRB.CreateICmpEQ(ThenLabel, IRB.getInt32(0));
  IRB.CreateCondBr(Cmp2, ThenBB2, EndBB2);

  // emscripten_longjmp(%__THREW__.val, threwValue);
  IRB.SetInsertPoint(ThenBB2);
  IRB.CreateCall(EmLongjmpF, {Threw, ThrewValue});
  IRB.CreateUnreachable();

  // __tempRet0 = threwValue;
  IRB.SetInsertPoint(EndBB2);
  IRB.CreateStore(ThrewValue, TempRet0GV);
  IRB.CreateBr(EndBB1);

  IRB.SetInsertPoint(ElseBB1);
  IRB.CreateBr(EndBB1);

  // longjmp_result = __tempRet0;
  IRB.SetInsertPoint(EndBB1);
  PHINode *LabelPHI = IRB.CreatePHI(IRB.getInt32Ty(), 2, "label");
  LabelPHI->addIncoming(ThenLabel, EndBB2);

  LabelPHI->addIncoming(IRB.getInt32(-1), ElseBB1);

  // Output parameter assignment
  Label = LabelPHI;
  EndBB = EndBB1;
  LongjmpResult = IRB.CreateLoad(TempRet0GV, "longjmp_result");
}
void TypeNodeCodeGen::visit(MethodCall* m)
{
    Place* self = getSelf(m);

    if ( const ScalarType* from = m->expr_->get().type_->cast<ScalarType>() )
    {
        Value* val = self->getScalar(builder_);
        const ScalarType* to = cast<ScalarType>( m->memberFct_->sig_.out_[0]->getType() );
        const llvm::Type* llvmTo = to->getLLVMType(ctxt_->module_);
        const llvm::Type* llvmFrom = from->getLLVMType(ctxt_->module_);

        if ( m->id()->find("bitcast") != std::string::npos )
            val = builder_.CreateBitCast(val, llvmTo);
        else // -> assumes that r is a normal cast
        {
            if ( llvmTo == llvmFrom )
            { 
                setResult(m, new Scalar(val));
                return;
            }

            llvm::StringRef name = val->getName();

            if ( from->isInteger() && to->isInteger() )
            {
                if ( from->sizeOf() > to->sizeOf() )
                    val = builder_.CreateTrunc(val, llvmTo, name);
                else
                {
                    // -> sizeof(from) < sizeof(to)
                    if ( from->isUnsigned() )
                        val = builder_.CreateZExt(val, llvmTo, name);
                    else
                        val = builder_.CreateSExt(val, llvmTo, name);
                }
            }
            else if ( from->isFloat() && to->isSigned() )   // fp -> si
                val = builder_.CreateFPToSI(val, llvmTo, name);
            else if ( from->isFloat() && to->isUnsigned() ) // fp -> ui
                val = builder_.CreateFPToUI(val, llvmTo, name);
            else if ( from->isSigned() && to->isFloat() )   // si -> fp
                val = builder_.CreateSIToFP(val, llvmTo, name);
            else if ( from->isUnsigned() && to->isFloat() ) // ui -> fp
                val = builder_.CreateUIToFP(val, llvmTo, name);
            else
            {
                swiftAssert( from->isFloat() && to->isFloat(), "must both be floats" );

                if ( from->sizeOf() > to->sizeOf() )
                    val = builder_.CreateFPTrunc(val, llvmTo, name);
                else // -> sizeof(from) < sizeof(to)
                    val = builder_.CreateFPExt(val, llvmTo, name);
            }
        }

        setResult( m, new Scalar(val) );
    }
    else
        emitCall(m, self);
}
Example #15
0
///Function:
// This function will get the sink values from the input file,
//and check the source dependent path for each of the sinks.
void ComputeSSO::getSinkSourceDependence(){

    std::map<llvm::GraphNode*, std::vector<GraphNode*> > result;
    std::pair<GraphNode*, int>  nearestDep;

    for(std::set<CallInst *>::iterator target = targetFunctions.begin(); target != targetFunctions.end();++target)
    {
        //get the value for the sink..
        Value* sink = (*target)->getCalledValue();
        //Value* sink = (*target)->getOp();
        result = depGraph->getEveryDependency(sink,inputDepValues,true);
        nearestDep = depGraph->getNearestDependency(sink,inputDepValues,true);
        // errs()<<" Nearest Dep Result: "<< (*nearestDep.first).getName();   //getName gives error:

        errs()<<"\n**********Sink**************        "<<  sink->getName()   <<"\n";
        // errs()<<
        typedef std::map<llvm::GraphNode*, std::vector<GraphNode*> >::iterator resultIterator;
        for(resultIterator res = result.begin();res!=result.end();++res)
        {
            errs()<<"Sink node: "<< res->first->getName() <<" Path : \n";
            typedef std::vector<GraphNode*>::iterator pathIterator;
            for(pathIterator path = res->second.begin(); path != res->second.end(); ++path)
            {
                errs()<<"    Path nodes: "<< (*path)->getName() <<"\n";
            }
        }
    }
}
//
// Method: visitRuntimeCheck()
//
// Description:
//  Visit a call to a run-time check (or related function) and insert pool
//  arguments where needed. PoolArgc is the number of initial pool arguments
//  that should be filled at the call site with pool handles for the
//  corresponding pointer arguments.
//
void
FuncTransform::visitRuntimeCheck (CallSite CS, const unsigned PoolArgc) {
  // A call to the runtime check should have positions for each pool argument
  // and the corresponding pointer.
  assert ((CS.arg_size() >= 2 * PoolArgc) &&
    "Not enough arguments to call of a runtime check!");

  for (unsigned PoolIndex = 0; PoolIndex < PoolArgc; ++PoolIndex) {
    //
    // Get the pool handle for the pointer argument.
    //
    Value *PH =
      getPoolHandle(CS.getArgument(PoolArgc + PoolIndex)->stripPointerCasts());

    //
    // Insert the pool handle into the run-time check.
    //
    if (PH) {
      Type * Int8Type  = Type::getInt8Ty(CS.getInstruction()->getContext());
      Type * VoidPtrTy = PointerType::getUnqual(Int8Type);
      PH = castTo (PH, VoidPtrTy, PH->getName(), CS.getInstruction());
      CS.setArgument (PoolIndex, PH);

      //
      // Record that we've used the pool here.
      //
      AddPoolUse (*(CS.getInstruction()), PH, PoolUses);
    }
  }
}
Example #17
0
static bool unpackStoreToAggregate(InstCombiner &IC, StoreInst &SI) {
  // FIXME: We could probably with some care handle both volatile and atomic
  // stores here but it isn't clear that this is important.
  if (!SI.isSimple())
    return false;

  Value *V = SI.getValueOperand();
  Type *T = V->getType();

  if (!T->isAggregateType())
    return false;

  if (auto *ST = dyn_cast<StructType>(T)) {
    // If the struct only have one element, we unpack.
    unsigned Count = ST->getNumElements();
    if (Count == 1) {
      V = IC.Builder->CreateExtractValue(V, 0);
      combineStoreToNewValue(IC, SI, V);
      return true;
    }

    // We don't want to break loads with padding here as we'd loose
    // the knowledge that padding exists for the rest of the pipeline.
    const DataLayout &DL = IC.getDataLayout();
    auto *SL = DL.getStructLayout(ST);
    if (SL->hasPadding())
      return false;

    SmallString<16> EltName = V->getName();
    EltName += ".elt";
    auto *Addr = SI.getPointerOperand();
    SmallString<16> AddrName = Addr->getName();
    AddrName += ".repack";
    auto *IdxType = Type::getInt32Ty(ST->getContext());
    auto *Zero = ConstantInt::get(IdxType, 0);
    for (unsigned i = 0; i < Count; i++) {
      Value *Indices[2] = {
        Zero,
        ConstantInt::get(IdxType, i),
      };
      auto *Ptr = IC.Builder->CreateInBoundsGEP(ST, Addr, makeArrayRef(Indices), AddrName);
      auto *Val = IC.Builder->CreateExtractValue(V, i, EltName);
      IC.Builder->CreateStore(Val, Ptr);
    }

    return true;
  }

  if (auto *AT = dyn_cast<ArrayType>(T)) {
    // If the array only have one element, we unpack.
    if (AT->getNumElements() == 1) {
      V = IC.Builder->CreateExtractValue(V, 0);
      combineStoreToNewValue(IC, SI, V);
      return true;
    }
  }

  return false;
}
int main(int argc, char *argv[]) {
  if (argc != 2) {
    std::cerr << "Usage: " << argv[0] << "bitcode_filename" << std::endl;
    return 1;
  }
  StringRef filename = argv[1];
  LLVMContext context;

  ErrorOr<std::unique_ptr<MemoryBuffer>> fileOrErr =
    MemoryBuffer::getFileOrSTDIN(filename);
  if (std::error_code ec = fileOrErr.getError()) {
    std::cerr << " Error opening input file: " + ec.message() << std::endl;
    return 2;
  }
  ErrorOr<llvm::Module *> moduleOrErr =
      parseBitcodeFile(fileOrErr.get()->getMemBufferRef(), context);
  if (std::error_code ec = fileOrErr.getError()) {
    std::cerr << "Error reading Moduule: " + ec.message() << std::endl;
    return 3;
  }

  Module *m = moduleOrErr.get();
  std::cout << "Successfully read Module:" << std::endl;
  std::cout << " Name: " << m->getName().str() << std::endl;
  std::cout << " Target triple: " << m->getTargetTriple() << std::endl;

  for (auto iter1 = m->getFunctionList().begin();
       iter1 != m->getFunctionList().end(); iter1++) {
    Function &f = *iter1;
    std::cout << " Function: " << f.getName().str() << std::endl;
    for (auto iter2 = f.getBasicBlockList().begin();
         iter2 != f.getBasicBlockList().end(); iter2++) {
      BasicBlock &bb = *iter2;
      std::cout << "  BasicBlock: " << bb.getName().str() << std::endl;
      for (auto iter3 = bb.begin(); iter3 != bb.end(); iter3++) {
        Instruction &inst = *iter3;
        std::cout << "   Instruction " << &inst << " : "
		  << inst.getOpcodeName();
	assert(isa<LoadInst>(inst) && "Is not a LLVM IR load instruction" );
	assert(inst.getopcode() == ADD && "inst is not LLVM IR add instruction");
	unsigned int  i = 0;
	unsigned int opnt_cnt = inst.getNumOperands();
        for(; i < opnt_cnt; ++i)
        {
          Value *opnd = inst.getOperand(i);
          std::string o;
          if (opnd->hasName()) {
            o = opnd->getName();
            std::cout << " " << o << "," ;
          } else {
            std::cout << " ptr" << opnd << ",";
          }
        }
        std:: cout << std::endl;
      }
    }
  }
  return 0;
}
Example #19
0
void DSWP::showLiveInfo(Loop *L) {
	cout << "live variable information" << endl;

	cout << "livein:   ";
	for (int i = 0; i < livein.size(); i++) {
		Value *val = livein[i];
		cout << val->getName().str() << "\t";
	}
	cout << endl;

	cout << "liveout:  ";
	for (int i = 0; i < liveout.size(); i++) {
		Value *val = liveout[i];
		cout << val->getName().str() << "\t";
	}
	cout << endl;
}
Example #20
0
util::ObjectNode ObjectNodeTraits<ui::hid::Device::Ptr>::serialized(const Value& value){
	util::ObjectNode ob;
	ob["name"].setValue(value->getName());
	ob["uuid"].setValue(value->getUuid());
	ob["channels"].setValue(value->getChannelNames());
	ob["allowTypicalControls"].setValue(value->allowsTypicalControls());
	return ob;
}
  virtual bool runOnFunction(Function &F) {
    bool Modified = false;
    for (Function::iterator I = F.begin(); I != F.end(); I++) {
      BasicBlock *BB = I;

      for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
        // Note: taking BI++ out of the for statement is important. Since this
        // loop may delete the instruction at *BI, this will invalidate the
        // iterator. So we make sure the iterator is incremented right from
        // the start and it already points to the next instruction. This way,
        // removing I from the basic block is harmless.
        Instruction &I = *BI++;

        // These nested conditions match a specific instruction pattern. We're
        // looking for a load whose address is a GEP constant expression.
        if (LoadInst *Load = dyn_cast<LoadInst>(&I)) {
          if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Load->getOperand(0))) {
            if (GEPOperator *GEP = dyn_cast<GEPOperator>(CE)) {
              Value *Ptr = GEP->getPointerOperand();

              // Only look for accesses to threadIdx with the expected amount of
              // GEP indices (essentially struct access to threadIdx.<member>.
              if (Ptr->getName() != "threadIdx" || GEP->getNumIndices() != 2) {
                continue;
              }

              // struct access as a GEP has two indices; read the LLVM
              // documentation on GEPs if this doesn't make sense.
              if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2))) {
                // Choose a function based on the index.
                uint64_t DimIndex = CI->getZExtValue();
                Function *TargetFunc;
                if (DimIndex == 0) {
                  TargetFunc = TidxRef;
                } else if (DimIndex == 1) {
                  TargetFunc = TidyRef;
                } else if (DimIndex == 2) {
                  TargetFunc = TidzRef;
                } else {
                  report_fatal_error("Invalid index for threadIdx access");
                }

                // Create a call instruction to the appropriate _tid* function
                // right before the load and replace the load by it.
                CallInst *TidFuncCall = CallInst::Create(TargetFunc, "", Load);
                TidFuncCall->takeName(Load);
                Load->replaceAllUsesWith(TidFuncCall);
                Load->eraseFromParent();
                Modified = true;
              }
            }
          }
        }
      }
    }

    return Modified;
  }
PointerAnalysisFlow* PointerAnalysis::operation_X_rY(PointerAnalysisFlow* in, Instruction* instruction) {
	errs()<<"Start x=&y analysis ================================="<<"\n";
	//Check that left operand is not null.
	
	if (isa<ConstantPointerNull>(instruction->getOperand(0))) {
		errs()<<"Null Pointer!!!"<<"\n";
		PointerAnalysisFlow* f = new PointerAnalysisFlow(in);
		Value* X = instruction->getOperand(1);
		if (isPointer(X) && isVariable(X)) {
			errs()<<"Remove  " <<X->getName()<<" from list"<<"\n";
			f->value.erase(X->getName());
		}
		
		//very important if value is empty, then it is a bottom
		if(f->value.size()==0) {
			f->triPoint=BOTTOM;
		}
		return f;
		//return execute_X_equals_NULL(in,instruction);
	}
	errs()<<"Not Null Pointer, move on"<<"\n";
	StoreInst* store = static_cast<StoreInst*>(instruction);
	PointerAnalysisFlow* f = new PointerAnalysisFlow(in);
	
	// X = &Y
	//Check if right  is a pointer
	if (store->getOperand(1)->getType()->isPointerTy()) {
		//Check if x y  names are variable
		if (store->getOperand(0)->getName()!="" && store->getOperand(1)->getName()!="") {

			PointerAnalysisFlow* ff = new PointerAnalysisFlow();
			set<string> s;
			map<string, set<string> >value;
			s.insert(store->getOperand(0)->getName());
			value[store->getOperand(1)->getName()] = s;
			// X now points to Y.
			ff->value = value;
			PointerAnalysisFlow* tmp = static_cast<PointerAnalysisFlow*>(ff->join(f));
			delete ff;
			delete f;
			f = tmp;
		}
	}
	return f;
}
Example #23
0
void MIPrinter::printIRValueReference(const Value &V) {
  OS << "%ir.";
  if (V.hasName()) {
    printLLVMNameWithoutPrefix(OS, V.getName());
    return;
  }
  // TODO: Serialize the unnamed IR value references.
  OS << "<unserializable ir value>";
}
Example #24
0
string instructionToString(Instruction* curr_Ins)
{
	Instruction *InsOp1, *InsOp2;
	Value *v;
	string op1="'",op2="'",exprsn,opcodeName,opc;
	LoadInst *LD;
	InsOp1 = cast<Instruction>(curr_Ins->getOperand(0));
	InsOp2 = cast<Instruction>(curr_Ins->getOperand(1));
	opcodeName=InsOp1->getOpcodeName();
	if(opcodeName=="load")
	{
		LD = cast<LoadInst>(curr_Ins->getOperand(0));
		v=LD->getOperand(0);
		op1=v->getName().str();
	}
	else
	{	
		op1=instructionToString(InsOp1);
	}
	opcodeName=InsOp2->getOpcodeName();
	if(opcodeName=="load")
	{
		LD = cast<LoadInst>(curr_Ins->getOperand(1));
		v=LD->getOperand(0);
		op2=v->getName().str();
	}
	else
	{
		op2=instructionToString(InsOp2);
	}
	switch(curr_Ins->getOpcode()){ 
							case Instruction::Add: opc="+";
													break;
							case Instruction::Sub: opc="-";
													break;
							case 21:			   opc="/";
													break;
							case Instruction::Mul: opc="*";
													break;}
	exprsn=op1+opc+op2;
	return exprsn;
}
Example #25
0
bool Scalarizer::visitBitCastInst(BitCastInst &BCI) {
  VectorType *DstVT = dyn_cast<VectorType>(BCI.getDestTy());
  VectorType *SrcVT = dyn_cast<VectorType>(BCI.getSrcTy());
  if (!DstVT || !SrcVT)
    return false;

  unsigned DstNumElems = DstVT->getNumElements();
  unsigned SrcNumElems = SrcVT->getNumElements();
  IRBuilder<> Builder(BCI.getParent(), &BCI);
  Scatterer Op0 = scatter(&BCI, BCI.getOperand(0));
  ValueVector Res;
  Res.resize(DstNumElems);

  if (DstNumElems == SrcNumElems) {
    for (unsigned I = 0; I < DstNumElems; ++I)
      Res[I] = Builder.CreateBitCast(Op0[I], DstVT->getElementType(),
                                     BCI.getName() + ".i" + Twine(I));
  } else if (DstNumElems > SrcNumElems) {
    // <M x t1> -> <N*M x t2>.  Convert each t1 to <N x t2> and copy the
    // individual elements to the destination.
    unsigned FanOut = DstNumElems / SrcNumElems;
    Type *MidTy = VectorType::get(DstVT->getElementType(), FanOut);
    unsigned ResI = 0;
    for (unsigned Op0I = 0; Op0I < SrcNumElems; ++Op0I) {
      Value *V = Op0[Op0I];
      Instruction *VI;
      // Look through any existing bitcasts before converting to <N x t2>.
      // In the best case, the resulting conversion might be a no-op.
      while ((VI = dyn_cast<Instruction>(V)) &&
             VI->getOpcode() == Instruction::BitCast)
        V = VI->getOperand(0);
      V = Builder.CreateBitCast(V, MidTy, V->getName() + ".cast");
      Scatterer Mid = scatter(&BCI, V);
      for (unsigned MidI = 0; MidI < FanOut; ++MidI)
        Res[ResI++] = Mid[MidI];
    }
  } else {
    // <N*M x t1> -> <M x t2>.  Convert each group of <N x t1> into a t2.
    unsigned FanIn = SrcNumElems / DstNumElems;
    Type *MidTy = VectorType::get(SrcVT->getElementType(), FanIn);
    unsigned Op0I = 0;
    for (unsigned ResI = 0; ResI < DstNumElems; ++ResI) {
      Value *V = UndefValue::get(MidTy);
      for (unsigned MidI = 0; MidI < FanIn; ++MidI)
        V = Builder.CreateInsertElement(V, Op0[Op0I++], Builder.getInt32(MidI),
                                        BCI.getName() + ".i" + Twine(ResI)
                                        + ".upto" + Twine(MidI));
      Res[ResI] = Builder.CreateBitCast(V, DstVT->getElementType(),
                                        BCI.getName() + ".i" + Twine(ResI));
    }
  }
  gather(&BCI, Res);
  return true;
}
Example #26
0
// Strip the symbol table of its names.
//
static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) {
  for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) {
    Value *V = VI->getValue();
    ++VI;
    if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage()) {
      if (!PreserveDbgInfo || !V->getName().startswith("llvm.dbg"))
        // Set name to "", removing from symbol table!
        V->setName("");
    }
  }
}
Example #27
0
/// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the
/// code necessary to compute the offset from the base pointer (without adding
/// in the base pointer).  Return the result as a signed integer of intptr size.
Value *InstCombiner::EmitGEPOffset(User *GEP) {
  TargetData &TD = *getTargetData();
  gep_type_iterator GTI = gep_type_begin(GEP);
  const Type *IntPtrTy = TD.getIntPtrType(GEP->getContext());
  Value *Result = Constant::getNullValue(IntPtrTy);

  // If the GEP is inbounds, we know that none of the addressing operations will
  // overflow in an unsigned sense.
  bool isInBounds = cast<GEPOperator>(GEP)->isInBounds();
  
  // Build a mask for high order bits.
  unsigned IntPtrWidth = TD.getPointerSizeInBits();
  uint64_t PtrSizeMask = ~0ULL >> (64-IntPtrWidth);

  for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e;
       ++i, ++GTI) {
    Value *Op = *i;
    uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
    if (ConstantInt *OpC = dyn_cast<ConstantInt>(Op)) {
      if (OpC->isZero()) continue;
      
      // Handle a struct index, which adds its field offset to the pointer.
      if (const StructType *STy = dyn_cast<StructType>(*GTI)) {
        Size = TD.getStructLayout(STy)->getElementOffset(OpC->getZExtValue());
        
        if (Size)
          Result = Builder->CreateAdd(Result, ConstantInt::get(IntPtrTy, Size),
                                      GEP->getName()+".offs");
        continue;
      }
      
      Constant *Scale = ConstantInt::get(IntPtrTy, Size);
      Constant *OC =
              ConstantExpr::getIntegerCast(OpC, IntPtrTy, true /*SExt*/);
      Scale = ConstantExpr::getMul(OC, Scale, isInBounds/*NUW*/);
      // Emit an add instruction.
      Result = Builder->CreateAdd(Result, Scale, GEP->getName()+".offs");
      continue;
    }
    // Convert to correct type.
    if (Op->getType() != IntPtrTy)
      Op = Builder->CreateIntCast(Op, IntPtrTy, true, Op->getName()+".c");
    if (Size != 1) {
      // We'll let instcombine(mul) convert this to a shl if possible.
      Op = Builder->CreateMul(Op, ConstantInt::get(IntPtrTy, Size),
                              GEP->getName()+".idx", isInBounds /*NUW*/);
    }

    // Emit an add instruction.
    Result = Builder->CreateAdd(Op, Result, GEP->getName()+".offs");
  }
  return Result;
}
Example #28
0
static Value *splitStore(StoreInst *Inst, ConversionState &State) {
  if (Inst->isVolatile() || Inst->isAtomic())
    report_fatal_error("Can't split volatile/atomic stores");
  if (cast<IntegerType>(Inst->getValueOperand()->getType())->getBitWidth() % 8
      != 0)
    report_fatal_error("Stores must be a multiple of 8 bits");

  Value *OrigPtr = State.getConverted(Inst->getPointerOperand());
  // OrigPtr is now a placeholder in recursive calls, and so has no name.
  if (OrigPtr->getName().empty())
    OrigPtr->setName(Inst->getPointerOperand()->getName());
  Value *OrigVal = State.getConverted(Inst->getValueOperand());
  unsigned Width = cast<IntegerType>(
      Inst->getValueOperand()->getType())->getBitWidth();
  unsigned LoWidth = Width;

  while (!isLegalSize(LoWidth)) LoWidth -= 8;
  IntegerType *LoType = IntegerType::get(Inst->getContext(), LoWidth);
  IntegerType *HiType = IntegerType::get(Inst->getContext(), Width - LoWidth);
  IRBuilder<> IRB(Inst->getParent(), Inst);

  Value *BCLo = IRB.CreateBitCast(
      OrigPtr,
      LoType->getPointerTo(),
      OrigPtr->getName() + ".loty");
  Value *LoTrunc = IRB.CreateTrunc(
      OrigVal, LoType, OrigVal->getName() + ".lo");
  IRB.CreateAlignedStore(LoTrunc, BCLo, Inst->getAlignment());

  Value *HiLShr = IRB.CreateLShr(
      OrigVal, LoWidth, OrigVal->getName() + ".hi.sh");
  Value *GEPHi = IRB.CreateConstGEP1_32(BCLo, 1, OrigPtr->getName() + ".hi");
  Value *HiTrunc = IRB.CreateTrunc(
      HiLShr, HiType, OrigVal->getName() + ".hi");
  Value *BCHi = IRB.CreateBitCast(
        GEPHi,
        HiType->getPointerTo(),
        OrigPtr->getName() + ".hity");

  Value *StoreHi = IRB.CreateStore(HiTrunc, BCHi);

  if (!isLegalSize(Width - LoWidth)) {
    // HiTrunc is still illegal, and is redundant with the truncate in the
    // recursive call, so just get rid of it.
    State.recordConverted(cast<Instruction>(HiTrunc), HiLShr,
                          /*TakeName=*/false);
    StoreHi = splitStore(cast<StoreInst>(StoreHi), State);
    // BCHi was still illegal, and has been replaced with a placeholder in the
    // recursive call. Since it is redundant with BCLo in the recursive call,
    // just splice it out entirely.
    State.recordConverted(cast<Instruction>(BCHi), GEPHi, /*TakeName=*/false);
  }
  State.recordConverted(Inst, StoreHi, /*TakeName=*/false);
  return StoreHi;
}
/// visitStrdupCall - Handle strdup().
///
void FuncTransform::visitStrdupCall(CallSite CS) {
  assert(CS.arg_end()-CS.arg_begin() == 1 && "strdup takes one argument!");
  Instruction *I = CS.getInstruction();
  assert (getDSNodeHFor(I).getNode() && "strdup has NULL DSNode!\n");
  Value *PH = getPoolHandle(I);

  Type* Int8Type = Type::getInt8Ty(CS.getInstruction()->getContext());


#if 0
  assert (PH && "PH for strdup is null!\n");
#else
  if (!PH) {
    errs() << "strdup: NoPH\n";
    return;
  }
#endif
  Value *OldPtr = CS.getArgument(0);

  static Type *VoidPtrTy = PointerType::getUnqual(Int8Type);
  if (OldPtr->getType() != VoidPtrTy)
    OldPtr = CastInst::CreatePointerCast(OldPtr, VoidPtrTy, OldPtr->getName(), I);

  std::string Name = I->getName(); I->setName("");
  Value* Opts[3] = {PH, OldPtr, 0};
  Instruction *V = CallInst::Create(PAInfo.PoolStrdup, Opts, Name, I);
  Instruction *Casted = V;
  if (V->getType() != I->getType())
    Casted = CastInst::CreatePointerCast(V, I->getType(), V->getName(), I);

  // Update def-use info
  I->replaceAllUsesWith(Casted);

  // If we are modifying the original function, update the DSGraph.
  if (!FI.Clone) {
    // V and Casted now point to whatever the original allocation did.
    G->getScalarMap().replaceScalar(I, V);
    if (V != Casted)
      G->getScalarMap()[Casted] = G->getScalarMap()[V];
  } else {             // Otherwise, update the NewToOldValueMap
    UpdateNewToOldValueMap(I, V, V != Casted ? Casted : 0);
  }

  // If this was an invoke, fix up the CFG.
  if (InvokeInst *II = dyn_cast<InvokeInst>(I)) {
    BranchInst::Create (II->getNormalDest(), I);
    II->getUnwindDest()->removePredecessor(II->getParent(), true);
  }

  // Remove old allocation instruction.
  I->eraseFromParent();
}
Example #30
0
unique_ptr<Variable> FunctionMapping::new_variable ( const Value &llval )
{
	std::stringstream ss;
	ss << "l_" << llval.getName().str();

	auto *v = new Variable (
			llvm_type_to_nts_type ( *llval.getType() ),
			ss.str()
	);

	m_vars.insert ( make_pair ( &llval, v ) );
	return unique_ptr<Variable> ( v );
}