示例#1
0
void IrGen::visit(AstFunDef& funDef) {
  const auto functionIr =
    static_cast<llvm::Function*>(funDef.ir().irAddrOfIrObject());
  assert(functionIr);

  if (m_builder.GetInsertBlock()) {
    m_BasicBlockStack.push(m_builder.GetInsertBlock());
  }
  m_builder.SetInsertPoint(
    BasicBlock::Create(llvmContext, "entry", functionIr));

  // Add all arguments to the symbol table and create their allocas. Also tell
  // llvm the name of each arg.
  Function::arg_iterator llvmArgIter = functionIr->arg_begin();
  auto astArgIter = funDef.declaredArgs().cbegin();
  for (/*nop*/; llvmArgIter != functionIr->arg_end();
       ++llvmArgIter, ++astArgIter) {
    allocateAndInitLocalIrObjectFor(
      **astArgIter, llvmArgIter, (*astArgIter)->name());
    llvmArgIter->setName((*astArgIter)->name());
  }

  Value* bodyVal = callAcceptOn(funDef.body());
  assert(bodyVal);
  if (funDef.body().objType().isVoid()) { m_builder.CreateRetVoid(); }
  else if (!funDef.body().objType().isNoreturn()) {
    m_builder.CreateRet(bodyVal);
  }

  if (!m_BasicBlockStack.empty()) {
    m_builder.SetInsertPoint(m_BasicBlockStack.top());
    m_BasicBlockStack.pop();
  }
}
示例#2
0
/// CloneFunction - Return a copy of the specified function, but without
/// embedding the function into another module.  Also, any references specified
/// in the VMap are changed to refer to their mapped value instead of the
/// original one.  If any of the arguments to the function are in the VMap,
/// the arguments are deleted from the resultant function.  The VMap is
/// updated to include mappings from all of the instructions and basicblocks in
/// the function from their old to new values.
///
Function *llvm::CloneFunction(const Function *F, ValueToValueMapTy &VMap,
                              bool ModuleLevelChanges,
                              ClonedCodeInfo *CodeInfo) {
  std::vector<Type*> ArgTypes;

  // The user might be deleting arguments to the function by specifying them in
  // the VMap.  If so, we need to not add the arguments to the arg ty vector
  //
  for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
       I != E; ++I)
    if (VMap.count(I) == 0)  // Haven't mapped the argument to anything yet?
      ArgTypes.push_back(I->getType());

  // Create a new function type...
  FunctionType *FTy = FunctionType::get(F->getFunctionType()->getReturnType(),
                                    ArgTypes, F->getFunctionType()->isVarArg());

  // Create the new function...
  Function *NewF = Function::Create(FTy, F->getLinkage(), F->getName());

  // Loop over the arguments, copying the names of the mapped arguments over...
  Function::arg_iterator DestI = NewF->arg_begin();
  for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
       I != E; ++I)
    if (VMap.count(I) == 0) {   // Is this argument preserved?
      DestI->setName(I->getName()); // Copy the name over...
      VMap[I] = DestI++;        // Add mapping to VMap
    }

  SmallVector<ReturnInst*, 8> Returns;  // Ignore returns cloned.
  CloneFunctionInto(NewF, F, VMap, ModuleLevelChanges, Returns, "", CodeInfo);
  return NewF;
}
示例#3
0
/// AddNoCaptureAttrs - Deduce nocapture attributes for the SCC.
bool FunctionAttrs::AddNoCaptureAttrs(const CallGraphSCC &SCC) {
  bool Changed = false;

  // Check each function in turn, determining which pointer arguments are not
  // captured.
  for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
    Function *F = (*I)->getFunction();

    if (F == 0)
      // External node - skip it;
      continue;

    // Definitions with weak linkage may be overridden at linktime with
    // something that writes memory, so treat them like declarations.
    if (F->isDeclaration() || F->mayBeOverridden())
      continue;

    for (Function::arg_iterator A = F->arg_begin(), E = F->arg_end(); A!=E; ++A)
      if (A->getType()->isPointerTy() && !A->hasNoCaptureAttr() &&
          !PointerMayBeCaptured(A, true, /*StoreCaptures=*/false)) {
        A->addAttr(Attribute::NoCapture);
        ++NumNoCapture;
        Changed = true;
      }
  }

  return Changed;
}
bool LLPE::runOnModule(Module &M) {
  
	vector<int> argv = readInputFile();

	for (Module::iterator F = M.begin(), F_end = M.end(); F != F_end; ++F) {

		for (Function::arg_iterator A = F->arg_begin(), A_end = F->arg_end(); A != A_end; ++A) {
		
			//Search for variables referencing argv
			if (A->getName() == "argv") {
				
				//Iterate through uses of argv
				for (Value::use_iterator U = A->use_begin(), U_end = A->use_end(); U != U_end; ++U) {
					Instruction *User = dyn_cast<Instruction>(*U);
					
					StoreInst *SI = dyn_cast<StoreInst>(User);
					AllocaInst *OrigAlloca = dyn_cast<AllocaInst>(SI->getOperand(1));
					
					for (Value::use_iterator U2 = OrigAlloca->use_begin(), U2_end = OrigAlloca->use_end(); U2 != U2_end; ++U2) {
						Instruction *User2 = dyn_cast<Instruction>(*U2);

						for (Value::use_iterator U3 = User2->use_begin(), U3_end = OrigAlloca->use_end(); U3 != U3_end; ++U3) {
							searchForStoreInstruction(dyn_cast<Instruction>(*U3)->getParent(), argv);
						}
					}

				}
			}
			
		}

	}
   
	return true;
}
bool StructuredModuleEditor::signaturesMatch(Function *First,
		Function *Second) {
	if (First == NULL || Second == NULL)
		return false;

	unsigned FirstNumArgs = First->arg_size();
	unsigned SecondNumArgs = Second->arg_size();

// The number of arguments passed to the old function must match the number of
// arguments passed to the new function
	if (FirstNumArgs != SecondNumArgs)
		return false;

// Both functions must abide by the same calling convention
	if (First->getCallingConv() != Second->getCallingConv())
		return false;

// Both functions must have the same return type
	if (First->getReturnType() != Second->getReturnType())
		return false;

// Checks that the arguments to the old function are of the same type as those of
// the new function, and also that they are in the same order
	for (Function::arg_iterator I = Second->arg_begin(), J = First->arg_begin(),
			IE = Second->arg_end(); I != IE; ++I, ++J) {
		if (I->getType() != J->getType())
			return false;
	}

	return true;
}
示例#6
0
void ExecutionState::dumpStack(llvm::raw_ostream &out) const {
  unsigned idx = 0;
  const KInstruction *target = prevPC;
  for (ExecutionState::stack_ty::const_reverse_iterator
         it = stack.rbegin(), ie = stack.rend();
       it != ie; ++it) {
    const StackFrame &sf = *it;
    Function *f = sf.kf->function;
    const InstructionInfo &ii = *target->info;
    out << "\t#" << idx++;
    std::stringstream AssStream;
    AssStream << std::setw(8) << std::setfill('0') << ii.assemblyLine;
    out << AssStream.str();
    out << " in " << f->getName().str() << " (";
    // Yawn, we could go up and print varargs if we wanted to.
    unsigned index = 0;
    for (Function::arg_iterator ai = f->arg_begin(), ae = f->arg_end();
         ai != ae; ++ai) {
      if (ai!=f->arg_begin()) out << ", ";

      out << ai->getName().str();
      // XXX should go through function
      ref<Expr> value = sf.locals[sf.kf->getArgRegister(index++)].value;
      if (value.get() && isa<ConstantExpr>(value))
        out << "=" << value;
    }
    out << ")";
    if (ii.file != "")
      out << " at " << ii.file << ":" << ii.line;
    out << "\n";
    target = sf.caller;
  }
}
示例#7
0
    ejsval
    Module_prototype_getOrInsertFunction(ejsval env, ejsval _this, int argc, ejsval *args)
    {
        Module *module = ((Module*)EJSVAL_TO_OBJECT(_this));

        REQ_UTF8_ARG(0, name);
        REQ_LLVM_TYPE_ARG(1, returnType);
        REQ_ARRAY_ARG(2, paramTypes);

        std::vector< llvm::Type*> param_types;
        for (int i = 0; i < EJSARRAY_LEN(paramTypes); i ++) {
            param_types.push_back (Type_GetLLVMObj(EJSDENSEARRAY_ELEMENTS(paramTypes)[i]));
        }

        llvm::FunctionType *FT = llvm::FunctionType::get(returnType, param_types, false);

        llvm::Function* f = static_cast< llvm::Function*>(module->llvm_module->getOrInsertFunction(name, FT));

        // XXX this needs to come from the js call, since when we hoist anonymous methods we'll need to give them a private linkage.
        f->setLinkage (llvm::Function::ExternalLinkage);

        // XXX the args might not be identifiers but might instead be destructuring expressions.  punt for now.

#if notyet
        // Set names for all arguments.
        unsigned Idx = 0;
        for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();
             ++AI, ++Idx)
            AI->setName(Args[Idx]);
#endif

        return Function_new (f);
    }
示例#8
0
Function *Codegen::Generate(PrototypeAST *proto) {
	string funcName = proto->GetName();
	vector<string> args = proto->GetArgs();

	vector<Type*> Doubles(args.size(), Type::getDoubleTy(getGlobalContext()));
	FunctionType *funcType = FunctionType::get(
			Type::getDoubleTy(getGlobalContext()), Doubles, false);
	Function* func = Function::Create(funcType, Function::ExternalLinkage,
			funcName, TheModule);

	if (func->getName() != funcName) {
		func->eraseFromParent();
		func = TheModule->getFunction(funcName);

		if ( !func->empty()) {
			BaseError::Throw<Function*>("Redefinition of function");
			return 0;
		}

		if (func->arg_size() != args.size()) {
			BaseError::Throw<Function*>("Redefinition of function with wrong number of arguments");
			return 0;
		}
	}

	unsigned idx = 0;
	for (Function::arg_iterator iterItem = func->arg_begin(); idx != args.size(); ++iterItem, ++idx) {
		iterItem->setName(args[idx]);
	}

	return func;
}
示例#9
0
Function* Codegen_Function_Declaration(project473::AstNodePtr declaration_node) {
  char* fname = strdup(declaration_node->nSymbolPtr->id); 
  std::string Name(fname);
  std::vector<Type*> formalvars;
  project473::AstNodePtr formalVar = declaration_node->children[0]; 
  while(formalVar) { 
    if(formalVar->nSymbolPtr->stype->kind == project473::INT) {
      formalvars.push_back(Type::getInt32Ty(getGlobalContext()));
      formalVar=formalVar->sibling;
    }
    else {
      printf("Error, formal variable is not an int, in line: %d", formalVar->nLinenumber);
    }
  }
  project473::Type* functionTypeList = declaration_node->nSymbolPtr->stype->function;
  FunctionType *FT;
  if(functionTypeList->kind==project473::INT) { 
     FT = FunctionType::get(Type::getInt32Ty(getGlobalContext()), formalvars, false);
  }
  else if(functionTypeList->kind==project473::VOID) {
    FT = FunctionType::get(Type::getVoidTy(getGlobalContext()), formalvars, false);
  }

  Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
  // Set names for all arguments. Reuse formalVar
  formalVar = declaration_node->children[0];
  for (Function::arg_iterator AI = F->arg_begin(); formalVar != NULL; ++AI, formalVar=formalVar->sibling) {
          std::string argName(formalVar->nSymbolPtr->id);
          AI->setName(argName);
  }
  Functions[Name] = F; //add the Function to the map of functions
  return F;
}
示例#10
0
void StackTrace::dump(std::ostream &out) const {
  unsigned idx = 0;

  for (stack_t::const_iterator it = contents.begin(); it != contents.end(); it++) {
    Function *f = it->first.first->function;
    const InstructionInfo &ii = *it->first.second->info;

    out << "\t#" << idx++
        << " " << std::setw(8) << std::setfill('0') << ii.assemblyLine
        << " in " << f->getName().str() << " (";

    unsigned index = 0;
    for (Function::arg_iterator ai = f->arg_begin(), ae = f->arg_end();
         ai != ae; ++ai) {
      if (ai!=f->arg_begin()) out << ", ";

      out << ai->getName().str();
      // XXX should go through function
      ref<Expr> value = it->second[index++];
      if (isa<ConstantExpr>(value))
        out << "=" << value;
    }
    out << ")";
    if (ii.file != "")
      out << " at " << ii.file << ":" << ii.line;
    out << "\n";
  }
}
示例#11
0
/// analyzeFunction - Fill in the current structure with information gleaned
/// from the specified function.
void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F,
                                                       const TargetData *TD) {
  Metrics.analyzeFunction(F, TD);

  // A function with exactly one return has it removed during the inlining
  // process (see InlineFunction), so don't count it.
  // FIXME: This knowledge should really be encoded outside of FunctionInfo.
  if (Metrics.NumRets==1)
    --Metrics.NumInsts;

  ArgumentWeights.reserve(F->arg_size());
  DenseMap<Value *, unsigned> PointerArgs;
  unsigned ArgIdx = 0;
  for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E;
       ++I, ++ArgIdx) {
    // Count how much code can be eliminated if one of the arguments is
    // a constant or an alloca.
    ArgumentWeights.push_back(ArgInfo(countCodeReductionForConstant(Metrics, I),
                                      countCodeReductionForAlloca(Metrics, I)));

    // If the argument is a pointer, also check for pairs of pointers where
    // knowing a fixed offset between them allows simplification. This pattern
    // arises mostly due to STL algorithm patterns where pointers are used as
    // random access iterators.
    if (!I->getType()->isPointerTy())
      continue;
    PointerArgs[I] = ArgIdx;
    countCodeReductionForPointerPair(Metrics, PointerArgs, I, ArgIdx);
  }
}
示例#12
0
Function *PrototypeAST::Codegen() {
  // Make the function type:  double(double,double) etc.
  std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
  FunctionType *FT =
      FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);

  Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
  // If F conflicted, there was already something named 'Name'.  If it has a
  // body, don't allow redefinition or reextern.
  if (F->getName() != Name) {
    // Delete the one we just made and get the existing one.
    F->eraseFromParent();
    F = TheModule->getFunction(Name);
    // If F already has a body, reject this.
    if (!F->empty()) {
      ErrorF("redefinition of function");
      return 0;
    }
    // If F took a different number of args, reject.
    if (F->arg_size() != Args.size()) {
      ErrorF("redefinition of function with different # args");
      return 0;
    }
  }

  // Set names for all arguments.
  unsigned Idx = 0;
  for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();
       ++AI, ++Idx)
    AI->setName(Args[Idx]);
    
  return F;
}
示例#13
0
void MemoryInstrumenter::instrumentPointerParameters(Function *F) {
  assert(F && !F->isDeclaration());
  Instruction *Entry = F->begin()->getFirstNonPHI();
  for (Function::arg_iterator AI = F->arg_begin(); AI != F->arg_end(); ++AI) {
    if (AI->getType()->isPointerTy())
      instrumentPointer(AI, NULL, Entry);
  }
}
示例#14
0
void MemoryInstrumenter::checkFeatures(Module &M) {
    // Check whether any memory allocation function can
    // potentially be pointed by function pointers.
    // Also, all intrinsic functions will be called directly,
    // i.e. not via function pointers.
    for (Module::iterator F = M.begin(); F != M.end(); ++F) {
        if (DynAAUtils::IsMalloc(F) || F->isIntrinsic()) {
            for (Value::use_iterator UI = F->use_begin(); UI != F->use_end(); ++UI) {
                User *Usr = *UI;
                assert(isa<CallInst>(Usr) || isa<InvokeInst>(Usr));
                CallSite CS(cast<Instruction>(Usr));
                for (unsigned i = 0; i < CS.arg_size(); ++i)
                    assert(CS.getArgument(i) != F);
            }
        }
    }

    // Check whether memory allocation functions are captured.
    for (Module::iterator F = M.begin(); F != M.end(); ++F) {
        // 0 is the return, 1 is the first parameter.
        if (F->isDeclaration() && F->doesNotAlias(0) && !DynAAUtils::IsMalloc(F)) {
            errs().changeColor(raw_ostream::RED);
            errs() << F->getName() << "'s return value is marked noalias, ";
            errs() << "but the function is not treated as malloc.\n";
            errs().resetColor();
        }
    }

    // Global variables shouldn't be of the array type.
    for (Module::global_iterator GI = M.global_begin(), E = M.global_end();
            GI != E; ++GI) {
        assert(!GI->getType()->isArrayTy());
    }
    // A function parameter or an instruction can be an array, but we don't
    // instrument such constructs for now. Issue a warning on such cases.
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
        for (Function::arg_iterator AI = F->arg_begin(); AI != F->arg_end(); ++AI) {
            if (AI->getType()->isArrayTy()) {
                errs().changeColor(raw_ostream::RED);
                errs() << F->getName() << ":" << *AI << " is an array\n";
                errs().resetColor();
            }
        }
    }
    for (Module::iterator F = M.begin(); F != M.end(); ++F) {
        for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) {
            for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) {
                if (Ins->getType()->isArrayTy()) {
                    errs().changeColor(raw_ostream::RED);
                    errs() << F->getName() << ":" << *Ins << " is an array\n";
                    errs().resetColor();
                }
            }
        }
    }
}
示例#15
0
/// cloneFunctionBody - Create a new function based on F and
/// insert it into module. Remove first argument. Use STy as
/// the return type for new function.
Function *SRETPromotion::cloneFunctionBody(Function *F, 
                                           const StructType *STy) {

  const FunctionType *FTy = F->getFunctionType();
  std::vector<const Type*> Params;

  // Attributes - Keep track of the parameter attributes for the arguments.
  SmallVector<AttributeWithIndex, 8> AttributesVec;
  const AttrListPtr &PAL = F->getAttributes();

  // Add any return attributes.
  if (Attributes attrs = PAL.getRetAttributes())
    AttributesVec.push_back(AttributeWithIndex::get(0, attrs));

  // Skip first argument.
  Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
  ++I;
  // 0th parameter attribute is reserved for return type.
  // 1th parameter attribute is for first 1st sret argument.
  unsigned ParamIndex = 2; 
  while (I != E) {
    Params.push_back(I->getType());
    if (Attributes Attrs = PAL.getParamAttributes(ParamIndex))
      AttributesVec.push_back(AttributeWithIndex::get(ParamIndex - 1, Attrs));
    ++I;
    ++ParamIndex;
  }

  // Add any fn attributes.
  if (Attributes attrs = PAL.getFnAttributes())
    AttributesVec.push_back(AttributeWithIndex::get(~0, attrs));


  FunctionType *NFTy = FunctionType::get(STy, Params, FTy->isVarArg());
  Function *NF = Function::Create(NFTy, F->getLinkage());
  NF->takeName(F);
  NF->copyAttributesFrom(F);
  NF->setAttributes(AttrListPtr::get(AttributesVec.begin(), AttributesVec.end()));
  F->getParent()->getFunctionList().insert(F, NF);
  NF->getBasicBlockList().splice(NF->begin(), F->getBasicBlockList());

  // Replace arguments
  I = F->arg_begin();
  E = F->arg_end();
  Function::arg_iterator NI = NF->arg_begin();
  ++I;
  while (I != E) {
    I->replaceAllUsesWith(NI);
    NI->takeName(I);
    ++I;
    ++NI;
  }

  return NF;
}
示例#16
0
int get_arg_count(const char *name, Function *op)
{
    uint8_t args_present[MAX_ARGS];
    int nb_args, i, n;
    const char *p;

    for(i = 0;i < MAX_ARGS; i++)
        args_present[i] = 0;

    // compute the number of arguments by looking at
    // the uses of the op parameters
    for (Function::arg_iterator i = op->arg_begin(), e = op->arg_end(); i != e; ++i) {
      const char *tmpArgName = i->getName().c_str();
      char *argName = (char *) malloc(strlen(tmpArgName + 1));
      strcpy(argName, tmpArgName);

      if (strstart(argName, "__op_param", &p)) {
	if (i->hasNUsesOrMore(1)) {
	  n = strtoul(p, NULL, 10);
	  if (n > MAX_ARGS)
	    error("too many arguments in %s", name);
	  args_present[n - 1] = 1;
	}
      }
    }

    for (i = 1; i <= MAX_ARGS; i++) {
      char *funcName = (char *) malloc(20);
      sprintf(funcName, "__op_gen_label%d", i);
      Function *f = ops->getFunction(std::string(funcName));
      if (f != NULL) {
	  for (Function::use_iterator j = f->use_begin(), e = f->use_end(); j != e; ++j) {
	      if (Instruction *inst = dyn_cast<Instruction>(*j)) {
		if (inst->getParent()->getParent() == op) {
		  args_present[i - 1] = 1;
		}
	      }
	  }
      } else {
	  std::cout << "symbol not found\n";
      }
    }

    nb_args = 0;
    while (nb_args < MAX_ARGS && args_present[nb_args])
        nb_args++;

    for(i = nb_args; i < MAX_ARGS; i++) {
        if (args_present[i])
            error("inconsistent argument numbering in %s", name);
    }

    return nb_args;
}
示例#17
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();
}
示例#18
0
void MemoryInstrumenter::checkFeatures(Module &M) {
  // Check whether any memory allocation function can
  // potentially be pointed by function pointers.
  // Also, all intrinsic functions will be called directly,
  // i.e. not via function pointers.
  for (Module::iterator F = M.begin(); F != M.end(); ++F) {
    if (DynAAUtils::IsMalloc(F) || F->isIntrinsic()) {
      for (Value::use_iterator UI = F->use_begin(); UI != F->use_end(); ++UI) {
        User *Usr = *UI;
        assert(isa<CallInst>(Usr) || isa<InvokeInst>(Usr));
        CallSite CS(cast<Instruction>(Usr));
        for (unsigned i = 0; i < CS.arg_size(); ++i)
          assert(CS.getArgument(i) != F);
      }
    }
  }

  // Check whether memory allocation functions are captured.
  for (Module::iterator F = M.begin(); F != M.end(); ++F) {
    // 0 is the return, 1 is the first parameter.
    if (F->isDeclaration() && F->doesNotAlias(0) && !DynAAUtils::IsMalloc(F)) {
      errs().changeColor(raw_ostream::RED);
      errs() << F->getName() << "'s return value is marked noalias, ";
      errs() << "but the function is not treated as malloc.\n";
      errs().resetColor();
    }
  }

  // Sequential types except pointer types shouldn't be used as the type of
  // an instruction, a function parameter, or a global variable.
  for (Module::global_iterator GI = M.global_begin(), E = M.global_end();
       GI != E; ++GI) {
    if (isa<SequentialType>(GI->getType()))
      assert(GI->getType()->isPointerTy());
  }
  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    for (Function::arg_iterator AI = F->arg_begin(); AI != F->arg_end(); ++AI) {
      if (isa<SequentialType>(AI->getType()))
        assert(AI->getType()->isPointerTy());
    }
  }
  for (Module::iterator F = M.begin(); F != M.end(); ++F) {
    for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) {
      for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) {
        if (isa<SequentialType>(Ins->getType()))
          assert(Ins->getType()->isPointerTy());
      }
    }
  }

  // We don't support multi-process programs for now.
  if (!HookFork)
    assert(M.getFunction("fork") == NULL);
}
示例#19
0
 virtual Value * materializeValueFor(Value * V) {
     if(Function * fn = dyn_cast<Function>(V)) {
         assert(fn->getParent() == src);
         Function * newfn = dest->getFunction(fn->getName());
         if(!newfn) {
             newfn = Function::Create(fn->getFunctionType(),fn->getLinkage(), fn->getName(),dest);
             newfn->copyAttributesFrom(fn);
         }
         if(!fn->isDeclaration() && newfn->isDeclaration() && copyGlobal(fn,data)) {
             for(Function::arg_iterator II = newfn->arg_begin(), I = fn->arg_begin(), E = fn->arg_end(); I != E; ++I, ++II) {
                 II->setName(I->getName());
                 VMap[I] = II;
             }
             VMap[fn] = newfn;
             SmallVector<ReturnInst*,8> Returns;
             CloneFunctionInto(newfn, fn, VMap, true, Returns, "", NULL, NULL, this);
         }
         return newfn;
     } else if(GlobalVariable * GV = dyn_cast<GlobalVariable>(V)) {
         GlobalVariable * newGV = dest->getGlobalVariable(GV->getName(),true);
         if(!newGV) {
             newGV = new GlobalVariable(*dest,GV->getType()->getElementType(),GV->isConstant(),GV->getLinkage(),NULL,GV->getName(),NULL,GlobalVariable::NotThreadLocal,GV->getType()->getAddressSpace());
             newGV->copyAttributesFrom(GV);
             if(!GV->isDeclaration()) {
                 if(!copyGlobal(GV,data)) {
                     newGV->setExternallyInitialized(true);
                 } else if(GV->hasInitializer()) {
                     Value * C = MapValue(GV->getInitializer(),VMap,RF_None,NULL,this);
                     newGV->setInitializer(cast<Constant>(C));
                 }
             }
         }
         return newGV;
     } else if(MDNode * MD = dyn_cast<MDNode>(V)) {
         DISubprogram SP(MD);
         if(DI != NULL && SP.isSubprogram()) {
             
             if(Function * OF = SP.getFunction()) {
                 Function * F = cast<Function>(MapValue(OF,VMap,RF_None,NULL,this));
                 DISubprogram NSP = DI->createFunction(SP.getContext(), SP.getName(), SP.getLinkageName(),
                                                   DI->createFile(SP.getFilename(),SP.getDirectory()),
                                                   SP.getLineNumber(), SP.getType(),
                                                   SP.isLocalToUnit(), SP.isDefinition(),
                                                   SP.getScopeLineNumber(),SP.getFlags(),SP.isOptimized(),
                                                   F);
                 return NSP;
             }
             /* fallthrough */
         }
         /* fallthrough */
     }
     return NULL;
 }
示例#20
0
文件: compiler.cpp 项目: glycerine/L3
Function *PrototypeAST::Codegen(Function*& preexistingPrototype /*out*/) {
  preexistingPrototype = NULL;

  // Make the function type:  double(double,double) etc.
  std::vector<const Type*> Doubles(Args.size(),
                                   Type::getDoubleTy(getGlobalContext()));
  FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
                                       Doubles, false);
  
  Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);

  
  // If F conflicted, there was already something named 'Name'.  If it has a
  // body, don't allow redefinition or reextern.
  if (F->getName() != Name) {

    // Delete the one we just made and get the existing one.
    F->eraseFromParent();
    F = TheModule->getFunction(Name);

    // If F already has a body, reject this.
    if (!F->empty()) {
      ErrorF("redefinition of function");
      return 0;
    }
    
    // If F took a different number of args, reject.
    if (F->arg_size() != Args.size()) {
      ErrorF("redefinition of function with different # args");
      return 0;
    }

    // if there is a preexisting prototype only -- without a body -- and with matching args
    // then inform caller of this, so that the FunctionAST::Codegen can not accidentally
    // delete it on body compilation failure.
    preexistingPrototype = F;
    //    printf("There was a pre-existing prototype for this function-- noting this fact: %p\n",preexistingPrototype);
  }
  
  // Set names for all arguments.
  unsigned Idx = 0;
  for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();
       ++AI, ++Idx) {
    AI->setName(Args[Idx]);
    
    // Add arguments to variable symbol table.
    NamedValues[Args[Idx]] = AI;
  }
  
  return F;
}
示例#21
0
void llvm::copyFunctionBody(Function &New, const Function &Orig,
                            ValueToValueMapTy &VMap) {
  if (!Orig.isDeclaration()) {
    Function::arg_iterator DestI = New.arg_begin();
    for (Function::const_arg_iterator J = Orig.arg_begin(); J != Orig.arg_end();
         ++J) {
      DestI->setName(J->getName());
      VMap[J] = DestI++;
    }

    SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned.
    CloneFunctionInto(&New, &Orig, VMap, /*ModuleLevelChanges=*/true, Returns);
  }
}
/* for the vi and lsup, find their corresponding argument*/
Value *FindFunctionArgumentOfInstr(Instruction *I, Function *F) {
  int notFound = 1;
  Value *via = 0;

  Function::arg_iterator FI = F->arg_begin(), FE = F->arg_end();
  while (FI != FE && notFound) {
    if (FI->getName() == I->getName()) {
      via = &*FI;
      notFound = 0;
    }
    ++FI;
  }
  return via;
}
示例#23
0
文件: toy.cpp 项目: B1ackCat/llvm-dsa
Function *PrototypeAST::Codegen() {
  // Make the function type:  double(double,double) etc.
  std::vector<Type *> Doubles(Args.size(),
                              Type::getDoubleTy(getGlobalContext()));
  FunctionType *FT =
      FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false);

  Function *F =
      Function::Create(FT, Function::ExternalLinkage, Name, TheModule);

  // If F conflicted, there was already something named 'Name'.  If it has a
  // body, don't allow redefinition or reextern.
  if (F->getName() != Name) {
    // Delete the one we just made and get the existing one.
    F->eraseFromParent();
    F = TheModule->getFunction(Name);

    // If F already has a body, reject this.
    if (!F->empty()) {
      ErrorF("redefinition of function");
      return 0;
    }

    // If F took a different number of args, reject.
    if (F->arg_size() != Args.size()) {
      ErrorF("redefinition of function with different # args");
      return 0;
    }
  }

  // Set names for all arguments.
  unsigned Idx = 0;
  for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();
       ++AI, ++Idx)
    AI->setName(Args[Idx]);

  // Create a subprogram DIE for this function.
  DIFile Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(),
                                     KSDbgInfo.TheCU->getDirectory());
  MDScope *FContext = Unit;
  unsigned LineNo = Line;
  unsigned ScopeLine = Line;
  DISubprogram SP = DBuilder->createFunction(
      FContext, Name, StringRef(), Unit, LineNo,
      CreateFunctionType(Args.size(), Unit), false /* internal linkage */,
      true /* definition */, ScopeLine, DebugNode::FlagPrototyped, false, F);

  KSDbgInfo.FnScopeMap[this] = SP;
  return F;
}
// Convert the given function to use normalized argument/return types.
static bool ConvertFunction(Function *Func) {
  FunctionType *FTy = Func->getFunctionType();
  FunctionType *NFTy = NormalizeFunctionType(FTy);
  if (NFTy == FTy)
    return false; // No change needed.
  Function *NewFunc = RecreateFunction(Func, NFTy);

  // Move the arguments across to the new function.
  for (Function::arg_iterator Arg = Func->arg_begin(), E = Func->arg_end(),
         NewArg = NewFunc->arg_begin();
       Arg != E; ++Arg, ++NewArg) {
    NewArg->takeName(Arg);
    if (Arg->getType() == NewArg->getType()) {
      Arg->replaceAllUsesWith(NewArg);
    } else {
      Instruction *Trunc = new TruncInst(
          NewArg, Arg->getType(), NewArg->getName() + ".arg_trunc",
          NewFunc->getEntryBlock().getFirstInsertionPt());
      Arg->replaceAllUsesWith(Trunc);
    }
  }

  if (FTy->getReturnType() != NFTy->getReturnType()) {
    // Fix up return instructions.
    Instruction::CastOps CastType =
        Func->getAttributes().hasAttribute(0, Attribute::SExt) ?
        Instruction::SExt : Instruction::ZExt;
    for (Function::iterator BB = NewFunc->begin(), E = NewFunc->end();
         BB != E;
         ++BB) {
      for (BasicBlock::iterator Iter = BB->begin(), E = BB->end();
           Iter != E; ) {
        Instruction *Inst = Iter++;
        if (ReturnInst *Ret = dyn_cast<ReturnInst>(Inst)) {
          Value *Ext = CopyDebug(
              CastInst::Create(CastType, Ret->getReturnValue(),
                               NFTy->getReturnType(),
                               Ret->getReturnValue()->getName() + ".ret_ext",
                               Ret),
              Ret);
          CopyDebug(ReturnInst::Create(Ret->getContext(), Ext, Ret), Ret);
          Ret->eraseFromParent();
        }
      }
    }
  }

  Func->eraseFromParent();
  return true;
}
示例#25
0
文件: codegen.cpp 项目: wujysh/Wlang
Value* NFunction::codeGen(CodeGenContext& context)
{
    vector<Type*> argTypes;
    for (ArgumentList::const_iterator it = arguments.begin();
         it != arguments.end(); it++) {
        argTypes.push_back(typeOf((*it)->type));
    }
    /* Create the top level interpreter function to call as entry */
    FunctionType *ftype = FunctionType::get(typeOf(returnType), argTypes, false);
    auto name = id.name;
    Function *function = Function::Create(ftype, GlobalValue::InternalLinkage, name.c_str(), context.module);

    if (name == "main")
        context.mainFunction = function;

    // If F conflicted, there was already something named 'Name'.  If it has a
    // body, don't allow redefinition or reextern.
    if (function->getName() != name) {
        // Delete the one we just made and get the existing one.
        function->eraseFromParent();
        function = context.module->getFunction(name);
    }
    /* Push a new variable/block context */
    BasicBlock *bblock = BasicBlock::Create(getGlobalContext(), "entry", function, 0);
    context.pushBlock(bblock);

    // Create arguments into symbol table
    unsigned index = 0;
    for (Function::arg_iterator iter = function->arg_begin(); index != arguments.size();
         ++iter, ++index) {
        auto name = arguments[index]->identifier.name;
        std::cout << name << std::endl;
        iter->setName(name);

        context.locals()[name] = iter;
    }

    // Create function body
    Value *last = nullptr;
    for (StatementList::const_iterator it = block.begin();
         it != block.end(); it++) {
        std::cout << "Generating code for " << typeid(**it).name() << ' ' << std::endl;
        last = (**it).codeGen(context);
    }

    context.popBlock();

    return last;
}
示例#26
0
Function *OMPGenerator::createSubfunctionDefinition() {
  Module *M = getModule();
  Function *F = Builder.GetInsertBlock()->getParent();
  std::vector<Type *> Arguments(1, Builder.getInt8PtrTy());
  FunctionType *FT = FunctionType::get(Builder.getVoidTy(), Arguments, false);
  Function *FN = Function::Create(FT, Function::InternalLinkage,
                                  F->getName() + ".omp_subfn", M);
  // Do not run any polly pass on the new function.
  FN->addFnAttr(PollySkipFnAttr);

  Function::arg_iterator AI = FN->arg_begin();
  AI->setName("omp.userContext");

  return FN;
}
示例#27
0
Function *ParallelLoopGenerator::createSubFnDefinition() {
  Function *F = Builder.GetInsertBlock()->getParent();
  std::vector<Type *> Arguments(1, Builder.getInt8PtrTy());
  FunctionType *FT = FunctionType::get(Builder.getVoidTy(), Arguments, false);
  Function *SubFn = Function::Create(FT, Function::InternalLinkage,
                                     F->getName() + ".polly.subfn", M);

  // Do not run any polly pass on the new function.
  SubFn->addFnAttr(PollySkipFnAttr);

  Function::arg_iterator AI = SubFn->arg_begin();
  AI->setName("polly.par.userContext");

  return SubFn;
}
示例#28
0
Function *Codegen::Generate(OperatorAST *opr) {
	NamedValues.clear();

	string opName = (opr->IsBinary() ? "binary" : "unary") + opr->GetOp();
	vector<string> args = opr->GetArgs();

	vector<Type*> Doubles(args.size(), Type::getDoubleTy(getGlobalContext()));
	FunctionType *funcType = FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false);
	Function* func = Function::Create(funcType, Function::ExternalLinkage, opName, TheModule);

	if (func->getName() != opName) {
		func->eraseFromParent();
		func = TheModule->getFunction(opName);

		if ( !func->empty()) {
			BaseError::Throw<Function*>("Redefinition of operator");
			return 0;
		}

		if (func->arg_size() != args.size()) {
			BaseError::Throw<Function*>("Redefinition of operator with wrong number of arguments");
			return 0;
		}
	}

	unsigned Idx = 0;
	for (Function::arg_iterator AI = func->arg_begin(); Idx != args.size(); ++AI, ++Idx) {
		AI->setName(args[Idx]);
	}

	// add the body
	BasicBlock *block = BasicBlock::Create(getGlobalContext(), "opfunc", func);
	Builder.SetInsertPoint(block);

	this->CreateArgumentAllocas(args, func);

	Value *retVal = this->Generate(opr->GetBody());
	if (retVal) {
		Builder.CreateRet(retVal);
		verifyFunction( *func);
		TheFPM->run( *func);
		return func;
	}

	func->eraseFromParent();
	return 0;
}
// Maybe make a clone, if a clone is made, return a pointer to it, if a clone
// was not made return nullptr.
Function *CSDataRando::makeFunctionClone(Function *F) {
  // Now we know how many arguments need to be passed, so we make the clones
  FuncInfo &FI = FunctionInfo[F];
  if (FI.ArgNodes.size() == 0) {
    // No additional args to pass, no need to clone.
    return nullptr;
  }
  // Determine the type of the new function, we insert the new parameters for
  // the masks after the normal arguments, but before any va_args
  Type *MaskTy = TypeBuilder<mask_t, false>::get(F->getContext());
  FunctionType *OldFuncTy = F->getFunctionType();
  std::vector<Type*> ArgTys;
  ArgTys.insert(ArgTys.end(), OldFuncTy->param_begin(), OldFuncTy->param_end());
  ArgTys.insert(ArgTys.end(), FI.ArgNodes.size(), MaskTy);
  FunctionType *CloneFuncTy = FunctionType::get(OldFuncTy->getReturnType(), ArgTys, OldFuncTy->isVarArg());

  Function *Clone = Function::Create(CloneFuncTy, Function::InternalLinkage, F->getName() + "_CONTEXT_SENSITIVE");
  F->getParent()->getFunctionList().insert(F->getIterator(), Clone);

  Function::arg_iterator CI = Clone->arg_begin(), CE = Clone->arg_end();

  // Map the old arguments to the clone arguments and set the name of the
  // clone arguments the same as the original.
  for (Function::arg_iterator i = F->arg_begin(), e = F->arg_end(); i != e && CI != CE; i++, CI++) {
    FI.OldToNewMap[&*i] = &*CI;
    CI->setName(i->getName());
  }

  // Set the name of the arg masks and associate them with the nodes they are
  // the masks for.
  for (unsigned i = 0, e = FI.ArgNodes.size(); i != e; ++i, ++CI) {
    CI->setName("arg_mask");
    FI.ArgMaskMap[FI.ArgNodes[i]] = &*CI;
  }

  SmallVector<ReturnInst*, 8> Returns;
  CloneFunctionInto(Clone, F, FI.OldToNewMap, false, Returns);
  Clone->setCallingConv(F->getCallingConv());

  // Invert OldToNewMap
  for (auto I : FI.OldToNewMap) {
    FI.NewToOldMap[I.second] = I.first;
  }

  NumClones++;
  return Clone;
}
示例#30
0
  std::vector<Type*> lowerJuliaArrayArgumentsDecl(Function* F) {
    std::vector<Type*> ArgTypes;
    Type* ReturnType = F->getReturnType();
    
    for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) {

      Type* argType = I->getType();
      if (is_jl_array_type(argType)) {
        ArgTypes.push_back(PointerType::get(ReturnType, 1));
      } else {
        ArgTypes.push_back(I->getType());
      }
      
    }

    return ArgTypes;
  }