예제 #1
0
파일: module.cpp 프로젝트: guangwong/echojs
    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);
    }
예제 #2
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;
}
예제 #3
0
파일: codegen.cpp 프로젝트: mxwang/hw6_473
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;
}
예제 #4
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;
}
예제 #5
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;
}
예제 #6
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();
  }
}
// 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;
}
예제 #8
0
파일: tllvmutil.cpp 프로젝트: 0----0/terra
 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;
 }
예제 #9
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;
}
예제 #10
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);
  }
}
예제 #11
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;
}
예제 #12
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;
}
예제 #13
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;
}
예제 #14
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;
}
예제 #15
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;
}
예제 #16
0
파일: gold-plugin.cpp 프로젝트: Drup/llvm
static GlobalObject *makeInternalReplacement(GlobalObject *GO) {
  Module *M = GO->getParent();
  GlobalObject *Ret;
  if (auto *F = dyn_cast<Function>(GO)) {
    if (F->isMaterializable()) {
      if (F->materialize())
        message(LDPL_FATAL, "LLVM gold plugin has failed to read a function");

    }

    auto *NewF = Function::Create(F->getFunctionType(), F->getLinkage(),
                                  F->getName(), M);

    ValueToValueMapTy VM;
    Function::arg_iterator NewI = NewF->arg_begin();
    for (auto &Arg : F->args()) {
      NewI->setName(Arg.getName());
      VM[&Arg] = NewI;
      ++NewI;
    }

    NewF->getBasicBlockList().splice(NewF->end(), F->getBasicBlockList());
    for (auto &BB : *NewF) {
      for (auto &Inst : BB)
        RemapInstruction(&Inst, VM, RF_IgnoreMissingEntries);
    }

    Ret = NewF;
    F->deleteBody();
  } else {
    auto *Var = cast<GlobalVariable>(GO);
    Ret = new GlobalVariable(
        *M, Var->getType()->getElementType(), Var->isConstant(),
        Var->getLinkage(), Var->getInitializer(), Var->getName(),
        nullptr, Var->getThreadLocalMode(), Var->getType()->getAddressSpace(),
        Var->isExternallyInitialized());
    Var->setInitializer(nullptr);
  }
  Ret->copyAttributesFrom(GO);
  Ret->setLinkage(GlobalValue::InternalLinkage);
  Ret->setComdat(GO->getComdat());

  return Ret;
}
예제 #17
0
Function* PrototypeAST::Codegen(){

	std::vector<Type*> array_type(this->func_args.size(), Type::getDoubleTy(getGlobalContext()));

	FunctionType *Func_type = FunctionType::get(Type::getDoubleTy(getGlobalContext()), array_type, false);


	//std::cout << "Current register function name is " << func_name << std::endl;


	Module *current_module = theHelper->getModuleForNewFunction();

	Function* func = Function::Create(Func_type, Function::ExternalLinkage, func_name, current_module);

	if (func == nullptr){
		Error("Fail to construct a function proto");
		return nullptr;
	}

	if (func->getName() != func_name){
		func->eraseFromParent();

		//在theHelper所有被JIT(Modules vector)或是没有JIT(openModule)的Modules中查找func;
		func = theHelper->getFunction(func_name);

		if (!func->empty()){
			ErrorF("redefinition of function");
			return nullptr;
		}

		if (func->arg_size() != func_args.size()){
			ErrorF("Differenct arguments given");
			return nullptr;
		}
	}

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

	return func;
}
예제 #18
0
Function *PrototypeAST::Codegen() {
  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);

  // conflicted, redefinition or reextern
  if (F->getName() != Name) {
    F->eraseFromParent();
    F = TheModule->getFunction(Name);

    if (!F->empty()) {
      ErrorF("redefinition of function");
      return 0;
    }

    if (F->arg_size() != Args.size()) {
      ErrorF("redefinition of function with different # args");
      return 0;
    }
  }

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

  DIFile Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(),
                                     KSDbgInfo.TheCU.getDirectory());
  DIDescriptor FContext(Unit);
  unsigned LineNo = Line;
  unsigned ScopeLine = Line;
  DISubprogram SP = DBuilder->createFunction(FContext, Name, StringRef(), Unit, LineNo,
                                             CreateFunctionType(Args.size(), Unit), false,
                                             true, ScopeLine, DIDescriptor::FlagPrototyped,
                                             false, F);
  KSDbgInfo.FnScopeMap[this] = SP;

  return F;
}
예제 #19
0
파일: PTXGenerator.cpp 프로젝트: CIB/polly
Function *PTXGenerator::createSubfunctionDefinition(int NumArgs) {
  assert(NumArgs == 1 && "we support only one array access now.");

  Module *M = getModule();
  Function *F = Builder.GetInsertBlock()->getParent();
  std::vector<Type *> Arguments;
  for (int i = 0; i < NumArgs; i++)
    Arguments.push_back(Builder.getInt8PtrTy());
  FunctionType *FT = FunctionType::get(Builder.getVoidTy(), Arguments, false);
  Function *FN = Function::Create(FT, Function::InternalLinkage,
                                  F->getName() + "_ptx_subfn", M);
  FN->setCallingConv(CallingConv::PTX_Kernel);

  // Do not run any optimization pass on the new function.
  P->getAnalysis<polly::ScopDetection>().markFunctionAsInvalid(FN);

  for (Function::arg_iterator AI = FN->arg_begin(); AI != FN->arg_end(); ++AI)
    AI->setName("ptx.Array");

  return FN;
}
예제 #20
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);

  // Certain backends (e.g., NVPTX) do not support '.'s in function names.
  // Hence, we ensure that all '.'s are replaced by '_'s.
  std::string FunctionName = SubFn->getName();
  std::replace(FunctionName.begin(), FunctionName.end(), '.', '_');
  SubFn->setName(FunctionName);

  // 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;
}
예제 #21
0
파일: toy.cpp 프로젝트: shepmaster/llvm
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);

    std::string FnName;
    FnName = MakeLegalFunctionName(Name);

    Module* M = TheHelper->getModuleForNewFunction();
    Function *F = Function::Create(FT, Function::ExternalLinkage, FnName, M);

    // FIXME: Implement duplicate function detection.
    // The check below will only work if the duplicate is in the open module.
    // If F conflicted, there was already something named 'Name'.  If it has a
    // body, don't allow redefinition or reextern.
    if (F->getName() != FnName) {
        // Delete the one we just made and get the existing one.
        F->eraseFromParent();
        F = M->getFunction(FnName);
        // 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;
}
예제 #22
0
Function *PrototypeAST::IRGen(IRGenContext &C) const {
  std::string FnName = MakeLegalFunctionName(Name);

  // 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, FnName,
                                 &C.getM());

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

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

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

  // 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;
}
예제 #23
0
파일: LinkModules.cpp 프로젝트: groue/llvm
// linkFunctionBody - Copy the source function over into the dest function and
// fix up references to values.  At this point we know that Dest is an external
// function, and that Src is not.
void ModuleLinker::linkFunctionBody(Function *Dst, Function *Src) {
  assert(Src && Dst && Dst->isDeclaration() && !Src->isDeclaration());

  // Go through and convert function arguments over, remembering the mapping.
  Function::arg_iterator DI = Dst->arg_begin();
  for (Function::arg_iterator I = Src->arg_begin(), E = Src->arg_end();
       I != E; ++I, ++DI) {
    DI->setName(I->getName());  // Copy the name over.

    // Add a mapping to our mapping.
    ValueMap[I] = DI;
  }

  if (Mode == Linker::DestroySource) {
    // Splice the body of the source function into the dest function.
    Dst->getBasicBlockList().splice(Dst->end(), Src->getBasicBlockList());
    
    // At this point, all of the instructions and values of the function are now
    // copied over.  The only problem is that they are still referencing values in
    // the Source function as operands.  Loop through all of the operands of the
    // functions and patch them up to point to the local versions.
    for (Function::iterator BB = Dst->begin(), BE = Dst->end(); BB != BE; ++BB)
      for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
        RemapInstruction(I, ValueMap, RF_IgnoreMissingEntries, &TypeMap);
    
  } else {
    // Clone the body of the function into the dest function.
    SmallVector<ReturnInst*, 8> Returns; // Ignore returns.
    CloneFunctionInto(Dst, Src, ValueMap, false, Returns, "", NULL, &TypeMap);
  }
  
  // There is no need to map the arguments anymore.
  for (Function::arg_iterator I = Src->arg_begin(), E = Src->arg_end();
       I != E; ++I)
    ValueMap.erase(I);
  
}
예제 #24
0
void function::Codegen(Module *TheModule, IRBuilder<> *Builder, std::map<std::string, Value*> &NamedValues){
  std::map<std::string, Value*> Values;		//Neue Map Damit die Nodes innerhalb der Funktion nicht in die NamedValues kommen
  Values.insert(NamedValues.begin(), NamedValues.end());
  vector<Type*> params = vector<Type*>();
  for(map<string,string>::iterator it = parameters.begin(); it != parameters.end(); ++it){
    params.push_back(getTypeFor(it->second));
  }
  FunctionType* FT = FunctionType::get(getTypeFor(returnType),
                                     params, false);
  Function* F = Function::Create(FT, Function::ExternalLinkage, name, TheModule);
  //übergabe der parameter
  Function::arg_iterator AI = F->arg_begin();
  for(std::map<std::string, std::string>::iterator it = parameters.begin(); it != parameters.end();  ++AI, ++it){
	   AI->setName(it->first);
	   Values[it->first] = AI;
  }

  BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", F);
  Builder->SetInsertPoint(BB);
  for(map<string, node*>::iterator it = variables.begin(); it != variables.end(); ++it){
    it->second->Codegen(TheModule, Builder, Values);
  }
  Builder->CreateRet(returnExp->Codegen(TheModule, Builder, Values));	//übergabe der kopierten Map
}
예제 #25
0
Value *UserFunctionSexp::codegen(SexpCompilerContext& ctx)
{
  vector<const Type*> doubles(args ? args->length(): 0, ctx.getDoubleTy());
  FunctionType *type = FunctionType::get(ctx.getDoubleTy(), doubles, false);
  Function *func = Function::Create(type, Function::ExternalLinkage, name, &ctx.getToplevelModule());

  if (args) {
    Function::arg_iterator it = func->arg_begin();
    ConsSexp *cons = args;
    SymbolSexp *sym;

    while (cons && (sym = dynamic_cast<SymbolSexp*>(cons->car))) {
      it->setName(sym->getName());
      cons = dynamic_cast<ConsSexp*>(cons->cdr);
      ++it;
    }
  }

  if (body) {
    BasicBlock *block = BasicBlock::Create(ctx.getLLVMContext(), "entry", func);
    Value *val = NULL;
    IRBuilder<> *builder = ctx.pushBuilder(block);

    for (ConsSexp *cons = body; cons; cons = dynamic_cast<ConsSexp*>(cons->cdr)) {
      if (cons->car)
        val = cons->car->codegen(ctx);
    }

    if (val)
      builder->CreateRet(val);
    
    ctx.popBuilder();
  }

  return func;
}
예제 #26
0
Function* ASTPrototype::Funcgen(CEnv& cenv)
{
	// Make the function type, e.g. double(double,double)
	vector<const Type*> Doubles(_args.size(), Type::DoubleTy);
	FunctionType* FT = FunctionType::get(Type::DoubleTy, Doubles, false);

	Function* f = Function::Create(
			FT, Function::ExternalLinkage, _name, cenv.module);

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

		// If F already has a body, reject this.
		if (!f->empty()) throw SyntaxError("Function redefined");

		// If F took a different number of args, reject.
		if (f->arg_size() != _args.size())
			throw SyntaxError("Function redefined with mismatched arguments");
	}

	// Set names for all arguments.
	size_t i = 0;
	for (Function::arg_iterator a = f->arg_begin(); i != _args.size();
	        ++a, ++i) {
		a->setName(_args[i]);

		// Add arguments to variable symbol table.
		cenv.env[_args[i]] = a;
	}

	return f;
}
예제 #27
0
//
// Method: buildBounce()
//
// Description:
//  Replaces the given call site with a call to a bounce function.  The
//  bounce function compares the function pointer to one of the given
//  target functions and calls the function directly if the pointer
//  matches.
//
Function*
Devirtualize::buildBounce (CallSite CS, std::vector<const Function*>& Targets) {
  //
  // Update the statistics on the number of bounce functions added to the
  // module.
  //
  ++FuncAdded;
  //
  // Create a bounce function that has a function signature almost identical
  // to the function being called.  The only difference is that it will have
  // an additional pointer argument at the beginning of its argument list that
  // will be the function to call.
  //
  Value* ptr = CS.getCalledValue();
  std::vector<Type *> TP;
  TP.insert (TP.begin(), ptr->getType());
  for (CallSite::arg_iterator i = CS.arg_begin();
       i != CS.arg_end();
       ++i) {
    TP.push_back ((*i)->getType());
  }

  FunctionType* NewTy = FunctionType::get(CS.getType(), TP, false);
  Module * M = CS.getInstruction()->getParent()->getParent()->getParent();
  Function* F = Function::Create (NewTy,
                                  GlobalValue::InternalLinkage,
                                  "devirtbounce",
                                  M);

  //
  // Set the names of the arguments.  Also, record the arguments in a vector
  // for subsequence access.
  //
  F->arg_begin()->setName("funcPtr");
  std::vector<Value*> fargs;
  for(Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end(); ai != ae; ++ai)
    if (ai != F->arg_begin()) {
      fargs.push_back(ai);
      ai->setName("arg");
    }

  //
  // Create an entry basic block for the function.  All it should do is perform
  // some cast instructions and branch to the first comparison basic block.
  //
  BasicBlock* entryBB = BasicBlock::Create (M->getContext(), "entry", F);

  //
  // For each function target, create a basic block that will call that
  // function directly.
  //
  std::map<const Function*, BasicBlock*> targets;
  for (unsigned index = 0; index < Targets.size(); ++index) {
    const Function* FL = Targets[index];

    // Create the basic block for doing the direct call
    BasicBlock* BL = BasicBlock::Create (M->getContext(), FL->getName(), F);
    targets[FL] = BL;
    // Create the direct function call
    Value* directCall = CallInst::Create ((Value *)FL,
                                          fargs,
                                          "",
                                          BL);

    // Add the return instruction for the basic block
    if (CS.getType()->isVoidTy())
      ReturnInst::Create (M->getContext(), BL);
    else
      ReturnInst::Create (M->getContext(), directCall, BL);
  }

  //
  // Create a failure basic block.  This basic block should simply be an
  // unreachable instruction.
  //
  BasicBlock * failBB = BasicBlock::Create (M->getContext(),
                                            "fail",
                                            F);
  new UnreachableInst (M->getContext(), failBB);

  //
  // Setup the entry basic block.  For now, just have it call the failure
  // basic block.  We'll change the basic block to which it branches later.
  //
  BranchInst * InsertPt = BranchInst::Create (failBB, entryBB);

  //
  // Create basic blocks which will test the value of the incoming function
  // pointer and branch to the appropriate basic block to call the function.
  //
  Type * VoidPtrType = getVoidPtrType (M->getContext());
  Value * FArg = castTo (F->arg_begin(), VoidPtrType, "", InsertPt);
  BasicBlock * tailBB = failBB;
  for (unsigned index = 0; index < Targets.size(); ++index) {
    //
    // Cast the function pointer to an integer.  This can go in the entry
    // block.
    //
    Value * TargetInt = castTo ((Value *)(Targets[index]),
                                VoidPtrType,
                                "",
                                InsertPt);

    //
    // Create a new basic block that compares the function pointer to the
    // function target.  If the function pointer matches, we'll branch to the
    // basic block performing the direct call for that function; otherwise,
    // we'll branch to the next function call target.
    //
    BasicBlock* TB = targets[Targets[index]];
    BasicBlock* newB = BasicBlock::Create (M->getContext(),
                                           "test." + Targets[index]->getName(),
                                           F);
    CmpInst * setcc = CmpInst::Create (Instruction::ICmp,
                                       CmpInst::ICMP_EQ,
                                       TargetInt,
                                       FArg,
                                       "sc",
                                       newB);
    BranchInst::Create (TB, tailBB, setcc, newB);

    //
    // Make this newly created basic block the next block that will be reached
    // when the next comparison will need to be done.
    //
    tailBB = newB;
  }

  //
  // Make the entry basic block branch to the first comparison basic block.
  //
  //InsertPt->setUnconditionalDest (tailBB);
  InsertPt->setSuccessor(0, tailBB);
  InsertPt->setSuccessor(1, tailBB);
  //
  // Return the newly created bounce function.
  //
  return F;
}
예제 #28
0
std::unique_ptr<Module> llvm::CloneModule(
    const Module *M, ValueToValueMapTy &VMap,
    std::function<bool(const GlobalValue *)> ShouldCloneDefinition) {
  // First off, we need to create the new module.
  std::unique_ptr<Module> New =
      llvm::make_unique<Module>(M->getModuleIdentifier(), M->getContext());
  New->setDataLayout(M->getDataLayout());
  New->setTargetTriple(M->getTargetTriple());
  New->setModuleInlineAsm(M->getModuleInlineAsm());
   
  // Loop over all of the global variables, making corresponding globals in the
  // new module.  Here we add them to the VMap and to the new Module.  We
  // don't worry about attributes or initializers, they will come later.
  //
  for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
       I != E; ++I) {
    GlobalVariable *GV = new GlobalVariable(*New, 
                                            I->getValueType(),
                                            I->isConstant(), I->getLinkage(),
                                            (Constant*) nullptr, I->getName(),
                                            (GlobalVariable*) nullptr,
                                            I->getThreadLocalMode(),
                                            I->getType()->getAddressSpace());
    GV->copyAttributesFrom(&*I);
    VMap[&*I] = GV;
  }

  // Loop over the functions in the module, making external functions as before
  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
    Function *NF =
        Function::Create(cast<FunctionType>(I->getValueType()),
                         I->getLinkage(), I->getName(), New.get());
    NF->copyAttributesFrom(&*I);
    VMap[&*I] = NF;
  }

  // Loop over the aliases in the module
  for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
       I != E; ++I) {
    if (!ShouldCloneDefinition(&*I)) {
      // An alias cannot act as an external reference, so we need to create
      // either a function or a global variable depending on the value type.
      // FIXME: Once pointee types are gone we can probably pick one or the
      // other.
      GlobalValue *GV;
      if (I->getValueType()->isFunctionTy())
        GV = Function::Create(cast<FunctionType>(I->getValueType()),
                              GlobalValue::ExternalLinkage, I->getName(),
                              New.get());
      else
        GV = new GlobalVariable(
            *New, I->getValueType(), false, GlobalValue::ExternalLinkage,
            (Constant *)nullptr, I->getName(), (GlobalVariable *)nullptr,
            I->getThreadLocalMode(), I->getType()->getAddressSpace());
      VMap[&*I] = GV;
      // We do not copy attributes (mainly because copying between different
      // kinds of globals is forbidden), but this is generally not required for
      // correctness.
      continue;
    }
    auto *GA = GlobalAlias::create(I->getValueType(),
                                   I->getType()->getPointerAddressSpace(),
                                   I->getLinkage(), I->getName(), New.get());
    GA->copyAttributesFrom(&*I);
    VMap[&*I] = GA;
  }
  
  // Now that all of the things that global variable initializer can refer to
  // have been created, loop through and copy the global variable referrers
  // over...  We also set the attributes on the global now.
  //
  for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
       I != E; ++I) {
    GlobalVariable *GV = cast<GlobalVariable>(VMap[&*I]);
    if (!ShouldCloneDefinition(&*I)) {
      // Skip after setting the correct linkage for an external reference.
      GV->setLinkage(GlobalValue::ExternalLinkage);
      continue;
    }
    if (I->hasInitializer())
      GV->setInitializer(MapValue(I->getInitializer(), VMap));
  }

  // Similarly, copy over function bodies now...
  //
  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
    Function *F = cast<Function>(VMap[&*I]);
    if (!ShouldCloneDefinition(&*I)) {
      // Skip after setting the correct linkage for an external reference.
      F->setLinkage(GlobalValue::ExternalLinkage);
      // Personality function is not valid on a declaration.
      F->setPersonalityFn(nullptr);
      continue;
    }
    if (!I->isDeclaration()) {
      Function::arg_iterator DestI = F->arg_begin();
      for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end();
           ++J) {
        DestI->setName(J->getName());
        VMap[&*J] = &*DestI++;
      }

      SmallVector<ReturnInst*, 8> Returns;  // Ignore returns cloned.
      CloneFunctionInto(F, &*I, VMap, /*ModuleLevelChanges=*/true, Returns);
    }

    if (I->hasPersonalityFn())
      F->setPersonalityFn(MapValue(I->getPersonalityFn(), VMap));
  }

  // And aliases
  for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
       I != E; ++I) {
    // We already dealt with undefined aliases above.
    if (!ShouldCloneDefinition(&*I))
      continue;
    GlobalAlias *GA = cast<GlobalAlias>(VMap[&*I]);
    if (const Constant *C = I->getAliasee())
      GA->setAliasee(MapValue(C, VMap));
  }

  // And named metadata....
  for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
         E = M->named_metadata_end(); I != E; ++I) {
    const NamedMDNode &NMD = *I;
    NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(NMD.getName());
    for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
      NewNMD->addOperand(MapMetadata(NMD.getOperand(i), VMap));
  }

  return New;
}
예제 #29
0
/// DoPromotion - This method actually performs the promotion of the specified
/// arguments, and returns the new function.  At this point, we know that it's
/// safe to do so.
CallGraphNode *ArgPromotion::DoPromotion(Function *F,
                               SmallPtrSet<Argument*, 8> &ArgsToPromote,
                              SmallPtrSet<Argument*, 8> &ByValArgsToTransform) {

  // Start by computing a new prototype for the function, which is the same as
  // the old function, but has modified arguments.
  const FunctionType *FTy = F->getFunctionType();
  std::vector<const Type*> Params;

  typedef std::set<IndicesVector> ScalarizeTable;

  // ScalarizedElements - If we are promoting a pointer that has elements
  // accessed out of it, keep track of which elements are accessed so that we
  // can add one argument for each.
  //
  // Arguments that are directly loaded will have a zero element value here, to
  // handle cases where there are both a direct load and GEP accesses.
  //
  std::map<Argument*, ScalarizeTable> ScalarizedElements;

  // OriginalLoads - Keep track of a representative load instruction from the
  // original function so that we can tell the alias analysis implementation
  // what the new GEP/Load instructions we are inserting look like.
  std::map<IndicesVector, LoadInst*> OriginalLoads;

  // Attributes - Keep track of the parameter attributes for the arguments
  // that we are *not* promoting. For the ones that we do promote, the parameter
  // attributes are lost
  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));

  // First, determine the new argument list
  unsigned ArgIndex = 1;
  for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E;
       ++I, ++ArgIndex) {
    if (ByValArgsToTransform.count(I)) {
      // Simple byval argument? Just add all the struct element types.
      const Type *AgTy = cast<PointerType>(I->getType())->getElementType();
      const StructType *STy = cast<StructType>(AgTy);
      for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
        Params.push_back(STy->getElementType(i));
      ++NumByValArgsPromoted;
    } else if (!ArgsToPromote.count(I)) {
      // Unchanged argument
      Params.push_back(I->getType());
      if (Attributes attrs = PAL.getParamAttributes(ArgIndex))
        AttributesVec.push_back(AttributeWithIndex::get(Params.size(), attrs));
    } else if (I->use_empty()) {
      // Dead argument (which are always marked as promotable)
      ++NumArgumentsDead;
    } else {
      // Okay, this is being promoted. This means that the only uses are loads
      // or GEPs which are only used by loads

      // In this table, we will track which indices are loaded from the argument
      // (where direct loads are tracked as no indices).
      ScalarizeTable &ArgIndices = ScalarizedElements[I];
      for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E;
           ++UI) {
        Instruction *User = cast<Instruction>(*UI);
        assert(isa<LoadInst>(User) || isa<GetElementPtrInst>(User));
        IndicesVector Indices;
        Indices.reserve(User->getNumOperands() - 1);
        // Since loads will only have a single operand, and GEPs only a single
        // non-index operand, this will record direct loads without any indices,
        // and gep+loads with the GEP indices.
        for (User::op_iterator II = User->op_begin() + 1, IE = User->op_end();
             II != IE; ++II)
          Indices.push_back(cast<ConstantInt>(*II)->getSExtValue());
        // GEPs with a single 0 index can be merged with direct loads
        if (Indices.size() == 1 && Indices.front() == 0)
          Indices.clear();
        ArgIndices.insert(Indices);
        LoadInst *OrigLoad;
        if (LoadInst *L = dyn_cast<LoadInst>(User))
          OrigLoad = L;
        else
          // Take any load, we will use it only to update Alias Analysis
          OrigLoad = cast<LoadInst>(User->use_back());
        OriginalLoads[Indices] = OrigLoad;
      }

      // Add a parameter to the function for each element passed in.
      for (ScalarizeTable::iterator SI = ArgIndices.begin(),
             E = ArgIndices.end(); SI != E; ++SI) {
        // not allowed to dereference ->begin() if size() is 0
        Params.push_back(GetElementPtrInst::getIndexedType(I->getType(),
                                                           SI->begin(),
                                                           SI->end()));
        assert(Params.back());
      }

      if (ArgIndices.size() == 1 && ArgIndices.begin()->empty())
        ++NumArgumentsPromoted;
      else
        ++NumAggregatesPromoted;
    }
  }

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

  const Type *RetTy = FTy->getReturnType();

  // Work around LLVM bug PR56: the CWriter cannot emit varargs functions which
  // have zero fixed arguments.
  bool ExtraArgHack = false;
  if (Params.empty() && FTy->isVarArg()) {
    ExtraArgHack = true;
    Params.push_back(Type::getInt32Ty(F->getContext()));
  }

  // Construct the new function type using the new arguments.
  FunctionType *NFTy = FunctionType::get(RetTy, Params, FTy->isVarArg());

  // Create the new function body and insert it into the module.
  Function *NF = Function::Create(NFTy, F->getLinkage(), F->getName());
  NF->copyAttributesFrom(F);

  
  DEBUG(dbgs() << "ARG PROMOTION:  Promoting to:" << *NF << "\n"
        << "From: " << *F);
  
  // Recompute the parameter attributes list based on the new arguments for
  // the function.
  NF->setAttributes(AttrListPtr::get(AttributesVec.begin(),
                                     AttributesVec.end()));
  AttributesVec.clear();

  F->getParent()->getFunctionList().insert(F, NF);
  NF->takeName(F);

  // Get the alias analysis information that we need to update to reflect our
  // changes.
  AliasAnalysis &AA = getAnalysis<AliasAnalysis>();

  // Get the callgraph information that we need to update to reflect our
  // changes.
  CallGraph &CG = getAnalysis<CallGraph>();
  
  // Get a new callgraph node for NF.
  CallGraphNode *NF_CGN = CG.getOrInsertFunction(NF);
  

  // Loop over all of the callers of the function, transforming the call sites
  // to pass in the loaded pointers.
  //
  SmallVector<Value*, 16> Args;
  while (!F->use_empty()) {
    CallSite CS = CallSite::get(F->use_back());
    assert(CS.getCalledFunction() == F);
    Instruction *Call = CS.getInstruction();
    const AttrListPtr &CallPAL = CS.getAttributes();

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

    // Loop over the operands, inserting GEP and loads in the caller as
    // appropriate.
    CallSite::arg_iterator AI = CS.arg_begin();
    ArgIndex = 1;
    for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
         I != E; ++I, ++AI, ++ArgIndex)
      if (!ArgsToPromote.count(I) && !ByValArgsToTransform.count(I)) {
        Args.push_back(*AI);          // Unmodified argument

        if (Attributes Attrs = CallPAL.getParamAttributes(ArgIndex))
          AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs));

      } else if (ByValArgsToTransform.count(I)) {
        // Emit a GEP and load for each element of the struct.
        const Type *AgTy = cast<PointerType>(I->getType())->getElementType();
        const StructType *STy = cast<StructType>(AgTy);
        Value *Idxs[2] = {
              ConstantInt::get(Type::getInt32Ty(F->getContext()), 0), 0 };
        for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
          Idxs[1] = ConstantInt::get(Type::getInt32Ty(F->getContext()), i);
          Value *Idx = GetElementPtrInst::Create(*AI, Idxs, Idxs+2,
                                                 (*AI)->getName()+"."+utostr(i),
                                                 Call);
          // TODO: Tell AA about the new values?
          Args.push_back(new LoadInst(Idx, Idx->getName()+".val", Call));
        }
      } else if (!I->use_empty()) {
        // Non-dead argument: insert GEPs and loads as appropriate.
        ScalarizeTable &ArgIndices = ScalarizedElements[I];
        // Store the Value* version of the indices in here, but declare it now
        // for reuse.
        std::vector<Value*> Ops;
        for (ScalarizeTable::iterator SI = ArgIndices.begin(),
               E = ArgIndices.end(); SI != E; ++SI) {
          Value *V = *AI;
          LoadInst *OrigLoad = OriginalLoads[*SI];
          if (!SI->empty()) {
            Ops.reserve(SI->size());
            const Type *ElTy = V->getType();
            for (IndicesVector::const_iterator II = SI->begin(),
                 IE = SI->end(); II != IE; ++II) {
              // Use i32 to index structs, and i64 for others (pointers/arrays).
              // This satisfies GEP constraints.
              const Type *IdxTy = (ElTy->isStructTy() ?
                    Type::getInt32Ty(F->getContext()) : 
                    Type::getInt64Ty(F->getContext()));
              Ops.push_back(ConstantInt::get(IdxTy, *II));
              // Keep track of the type we're currently indexing.
              ElTy = cast<CompositeType>(ElTy)->getTypeAtIndex(*II);
            }
            // And create a GEP to extract those indices.
            V = GetElementPtrInst::Create(V, Ops.begin(), Ops.end(),
                                          V->getName()+".idx", Call);
            Ops.clear();
            AA.copyValue(OrigLoad->getOperand(0), V);
          }
          // Since we're replacing a load make sure we take the alignment
          // of the previous load.
          LoadInst *newLoad = new LoadInst(V, V->getName()+".val", Call);
          newLoad->setAlignment(OrigLoad->getAlignment());
          Args.push_back(newLoad);
          AA.copyValue(OrigLoad, Args.back());
        }
      }

    if (ExtraArgHack)
      Args.push_back(Constant::getNullValue(Type::getInt32Ty(F->getContext())));

    // Push any varargs arguments on the list.
    for (; AI != CS.arg_end(); ++AI, ++ArgIndex) {
      Args.push_back(*AI);
      if (Attributes Attrs = CallPAL.getParamAttributes(ArgIndex))
        AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs));
    }

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

    Instruction *New;
    if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
      New = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(),
                               Args.begin(), Args.end(), "", Call);
      cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
      cast<InvokeInst>(New)->setAttributes(AttrListPtr::get(AttributesVec.begin(),
                                                          AttributesVec.end()));
    } else {
      New = CallInst::Create(NF, Args.begin(), Args.end(), "", Call);
      cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
      cast<CallInst>(New)->setAttributes(AttrListPtr::get(AttributesVec.begin(),
                                                        AttributesVec.end()));
      if (cast<CallInst>(Call)->isTailCall())
        cast<CallInst>(New)->setTailCall();
    }
    Args.clear();
    AttributesVec.clear();

    // Update the alias analysis implementation to know that we are replacing
    // the old call with a new one.
    AA.replaceWithNewValue(Call, New);

    // Update the callgraph to know that the callsite has been transformed.
    CallGraphNode *CalleeNode = CG[Call->getParent()->getParent()];
    CalleeNode->replaceCallEdge(Call, New, NF_CGN);

    if (!Call->use_empty()) {
      Call->replaceAllUsesWith(New);
      New->takeName(Call);
    }

    // Finally, remove the old call from the program, reducing the use-count of
    // F.
    Call->eraseFromParent();
  }

  // Since we have now created the new function, splice the body of the old
  // function right into the new function, leaving the old rotting hulk of the
  // function empty.
  NF->getBasicBlockList().splice(NF->begin(), F->getBasicBlockList());

  // Loop over the argument list, transfering uses of the old arguments over to
  // the new arguments, also transfering over the names as well.
  //
  for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(),
       I2 = NF->arg_begin(); I != E; ++I) {
    if (!ArgsToPromote.count(I) && !ByValArgsToTransform.count(I)) {
      // If this is an unmodified argument, move the name and users over to the
      // new version.
      I->replaceAllUsesWith(I2);
      I2->takeName(I);
      AA.replaceWithNewValue(I, I2);
      ++I2;
      continue;
    }

    if (ByValArgsToTransform.count(I)) {
      // In the callee, we create an alloca, and store each of the new incoming
      // arguments into the alloca.
      Instruction *InsertPt = NF->begin()->begin();

      // Just add all the struct element types.
      const Type *AgTy = cast<PointerType>(I->getType())->getElementType();
      Value *TheAlloca = new AllocaInst(AgTy, 0, "", InsertPt);
      const StructType *STy = cast<StructType>(AgTy);
      Value *Idxs[2] = {
            ConstantInt::get(Type::getInt32Ty(F->getContext()), 0), 0 };

      for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
        Idxs[1] = ConstantInt::get(Type::getInt32Ty(F->getContext()), i);
        Value *Idx = 
          GetElementPtrInst::Create(TheAlloca, Idxs, Idxs+2,
                                    TheAlloca->getName()+"."+Twine(i), 
                                    InsertPt);
        I2->setName(I->getName()+"."+Twine(i));
        new StoreInst(I2++, Idx, InsertPt);
      }

      // Anything that used the arg should now use the alloca.
      I->replaceAllUsesWith(TheAlloca);
      TheAlloca->takeName(I);
      AA.replaceWithNewValue(I, TheAlloca);
      continue;
    }

    if (I->use_empty()) {
      AA.deleteValue(I);
      continue;
    }

    // Otherwise, if we promoted this argument, then all users are load
    // instructions (or GEPs with only load users), and all loads should be
    // using the new argument that we added.
    ScalarizeTable &ArgIndices = ScalarizedElements[I];

    while (!I->use_empty()) {
      if (LoadInst *LI = dyn_cast<LoadInst>(I->use_back())) {
        assert(ArgIndices.begin()->empty() &&
               "Load element should sort to front!");
        I2->setName(I->getName()+".val");
        LI->replaceAllUsesWith(I2);
        AA.replaceWithNewValue(LI, I2);
        LI->eraseFromParent();
        DEBUG(dbgs() << "*** Promoted load of argument '" << I->getName()
              << "' in function '" << F->getName() << "'\n");
      } else {
        GetElementPtrInst *GEP = cast<GetElementPtrInst>(I->use_back());
        IndicesVector Operands;
        Operands.reserve(GEP->getNumIndices());
        for (User::op_iterator II = GEP->idx_begin(), IE = GEP->idx_end();
             II != IE; ++II)
          Operands.push_back(cast<ConstantInt>(*II)->getSExtValue());

        // GEPs with a single 0 index can be merged with direct loads
        if (Operands.size() == 1 && Operands.front() == 0)
          Operands.clear();

        Function::arg_iterator TheArg = I2;
        for (ScalarizeTable::iterator It = ArgIndices.begin();
             *It != Operands; ++It, ++TheArg) {
          assert(It != ArgIndices.end() && "GEP not handled??");
        }

        std::string NewName = I->getName();
        for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
            NewName += "." + utostr(Operands[i]);
        }
        NewName += ".val";
        TheArg->setName(NewName);

        DEBUG(dbgs() << "*** Promoted agg argument '" << TheArg->getName()
              << "' of function '" << NF->getName() << "'\n");

        // All of the uses must be load instructions.  Replace them all with
        // the argument specified by ArgNo.
        while (!GEP->use_empty()) {
          LoadInst *L = cast<LoadInst>(GEP->use_back());
          L->replaceAllUsesWith(TheArg);
          AA.replaceWithNewValue(L, TheArg);
          L->eraseFromParent();
        }
        AA.deleteValue(GEP);
        GEP->eraseFromParent();
      }
    }

    // Increment I2 past all of the arguments added for this promoted pointer.
    for (unsigned i = 0, e = ArgIndices.size(); i != e; ++i)
      ++I2;
  }

  // Notify the alias analysis implementation that we inserted a new argument.
  if (ExtraArgHack)
    AA.copyValue(Constant::getNullValue(Type::getInt32Ty(F->getContext())), 
                 NF->arg_begin());


  // Tell the alias analysis that the old function is about to disappear.
  AA.replaceWithNewValue(F, NF);

  
  NF_CGN->stealCalledFunctionsFrom(CG[F]);
  
  // Now that the old function is dead, delete it.  If there is a dangling
  // reference to the CallgraphNode, just leave the dead function around for
  // someone else to nuke.
  CallGraphNode *CGN = CG[F];
  if (CGN->getNumReferences() == 0)
    delete CG.removeFunctionFromModule(CGN);
  else
    F->setLinkage(Function::ExternalLinkage);
  
  return NF_CGN;
}
예제 #30
0
Function *ABIMethodSignature::createFunction(GenIR &Reader, Module &M) {
  // Compute the function type
  LLVMContext &Context = M.getContext();
  bool HasIndirectResult = Result.getKind() == ABIArgInfo::Indirect;
  uint32_t NumExtraArgs = HasIndirectResult ? 1 : 0;
  const uint32_t NumArgs = Args.size() + NumExtraArgs;
  int32_t ResultIndex = -1;
  SmallVector<Type *, 16> ArgumentTypes(NumArgs);
  SmallVector<AttributeSet, 16> Attrs(NumArgs + 1);

  if (HasIndirectResult) {
    ResultIndex = Signature->hasThis() ? 1 : 0;
    Result.setIndex((uint32_t)ResultIndex);
    ArgumentTypes[ResultIndex] = Reader.getManagedPointerType(Result.getType());
  } else {
    AttrBuilder RetAttrs;

    if (Result.getKind() == ABIArgInfo::ZeroExtend) {
      RetAttrs.addAttribute(Attribute::ZExt);
    } else if (Result.getKind() == ABIArgInfo::SignExtend) {
      RetAttrs.addAttribute(Attribute::SExt);
    }

    if (RetAttrs.hasAttributes()) {
      Attrs.push_back(
          AttributeSet::get(Context, AttributeSet::ReturnIndex, RetAttrs));
    }
  }

  uint32_t I = 0;
  for (auto &Arg : Args) {
    AttrBuilder ArgAttrs;

    if (ResultIndex >= 0 && I == (uint32_t)ResultIndex) {
      I++;
    }

    if (Arg.getKind() == ABIArgInfo::Indirect) {
      // TODO: byval attribute support
      ArgumentTypes[I] = Reader.getManagedPointerType(Arg.getType());
    } else {
      ArgumentTypes[I] = Arg.getType();

      if (Arg.getKind() == ABIArgInfo::ZeroExtend) {
        ArgAttrs.addAttribute(Attribute::ZExt);
      } else if (Arg.getKind() == ABIArgInfo::SignExtend) {
        ArgAttrs.addAttribute(Attribute::SExt);
      }

      if (ArgAttrs.hasAttributes()) {
        const unsigned Idx = I + 1; // Add one to accomodate the return attrs.
        Attrs.push_back(AttributeSet::get(Context, Idx, ArgAttrs));
      }
    }
    Arg.setIndex(I);

    I++;
  }

  const bool IsVarArg = false;
  FunctionType *FunctionTy =
      FunctionType::get(FuncResultType, ArgumentTypes, IsVarArg);
  Function *F = Function::Create(FunctionTy, Function::ExternalLinkage,
                                 M.getModuleIdentifier(), &M);

  // Use "param" for these initial parameter values. Numbering here
  // is strictly positional (hence includes implicit parameters).
  uint32_t N = 0;
  for (Function::arg_iterator Args = F->arg_begin(); Args != F->arg_end();
       Args++) {
    Args->setName(Twine("param") + Twine(N++));
  }

  CallingConv::ID CC;
  if (Signature->hasSecretParameter()) {
    assert((--F->arg_end())->getType()->isIntegerTy());

    AttrBuilder SecretParamAttrs;
    SecretParamAttrs.addAttribute("CLR_SecretParameter");
    Attrs.push_back(
        AttributeSet::get(Context, F->arg_size(), SecretParamAttrs));

    CC = CallingConv::CLR_SecretParameter;
  } else {
    CC = CallingConv::C;
  }
  F->setCallingConv(CC);

  if (Attrs.size() > 0) {
    F->setAttributes(AttributeSet::get(Context, Attrs));
  }

  if (Reader.JitContext->Options->DoInsertStatepoints) {
    F->setGC("coreclr");
  }

  return F;
}