예제 #1
0
static void radeon_llvm_optimize(LLVMModuleRef mod)
{
	const char *data_layout = LLVMGetDataLayout(mod);
	LLVMTargetDataRef TD = LLVMCreateTargetData(data_layout);
	LLVMPassManagerBuilderRef builder = LLVMPassManagerBuilderCreate();
	LLVMPassManagerRef pass_manager = LLVMCreatePassManager();

	/* Functions calls are not supported yet, so we need to inline
	 * everything.  The most efficient way to do this is to add
	 * the always_inline attribute to all non-kernel functions
	 * and then run the Always Inline pass.  The Always Inline
	 * pass will automaically inline functions with this attribute
	 * and does not perform the expensive cost analysis that the normal
	 * inliner does.
	 */

	LLVMValueRef fn;
	for (fn = LLVMGetFirstFunction(mod); fn; fn = LLVMGetNextFunction(fn)) {
		/* All the non-kernel functions have internal linkage */
		if (LLVMGetLinkage(fn) == LLVMInternalLinkage) {
			LLVMAddFunctionAttr(fn, LLVMAlwaysInlineAttribute);
		}
	}

	LLVMAddTargetData(TD, pass_manager);
	LLVMAddAlwaysInlinerPass(pass_manager);
	LLVMPassManagerBuilderPopulateModulePassManager(builder, pass_manager);

	LLVMRunPassManager(pass_manager, mod);
	LLVMPassManagerBuilderDispose(builder);
	LLVMDisposePassManager(pass_manager);
	LLVMDisposeTargetData(TD);
}
예제 #2
0
/* ExecutionEngine.t -> Llvm_target.DataLayout.t */
CAMLprim value llvm_ee_get_data_layout(LLVMExecutionEngineRef EE) {
  value DataLayout;
  LLVMTargetDataRef OrigDataLayout;
  char* TargetDataCStr;

  OrigDataLayout = LLVMGetExecutionEngineTargetData(EE);
  TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout);
  DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr));
  LLVMDisposeMessage(TargetDataCStr);

  return DataLayout;
}
예제 #3
0
파일: TranslateExpr.c 프로젝트: YuKill/ftc
static LLVMValueRef
translateArrayExpr(SymbolTable *TyTable, SymbolTable *ValTable, ASTNode *Node) {
  PtrVector *V = &(Node->Child);

  ASTNode *SizeNode = (ASTNode*) ptrVectorGet(V, 0),
          *InitNode = (ASTNode*) ptrVectorGet(V, 1);
  Type    *ThisType  = createType(IdTy, Node->Value);

  LLVMTypeRef ArrayType = getLLVMTypeFromType(TyTable, ThisType);

  LLVMValueRef SizeVal = translateExpr(TyTable, ValTable, SizeNode),
               InitVal = translateExpr(TyTable, ValTable, InitNode);

  LLVMValueRef ArrayVal = LLVMBuildArrayMalloc(Builder, ArrayType, SizeVal, "");

  // This BasicBlock and ThisFunction
  LLVMBasicBlockRef ThisBB = LLVMGetInsertBlock(Builder);
  LLVMValueRef      ThisFn = LLVMGetBasicBlockParent(ThisBB);

  LLVMValueRef Counter = LLVMBuildAlloca(Builder, LLVMInt32Type(), "");
  LLVMBuildStore(Builder, LLVMConstInt(LLVMInt32Type(), 0, 1), Counter);

  LLVMTargetDataRef DataRef = LLVMCreateTargetData(LLVMGetDataLayout(Module));
  unsigned long long Size = LLVMStoreSizeOfType(DataRef, ArrayType);

  LLVMBasicBlockRef InitBB, MidBB, EndBB;

  InitBB = LLVMAppendBasicBlock(ThisFn, "for.init");
  EndBB  = LLVMAppendBasicBlock(ThisFn, "for.end");
  MidBB  = LLVMAppendBasicBlock(ThisFn, "for.mid");

  LLVMBuildBr(Builder, InitBB);

  LLVMPositionBuilderAtEnd(Builder, InitBB);
  LLVMValueRef CurrentCounter = LLVMBuildLoad(Builder, Counter, "");
  LLVMValueRef Comparation    = LLVMBuildICmp(Builder, LLVMIntSLT, CurrentCounter, SizeVal, "");
  LLVMBuildCondBr(Builder, Comparation, MidBB, EndBB);

  LLVMPositionBuilderAtEnd(Builder, MidBB);
  CurrentCounter = LLVMBuildLoad(Builder, Counter, "");
  LLVMValueRef TheValue = LLVMBuildLoad(Builder, InitVal, ""); 
  LLVMValueRef ElemIdx[] = { LLVMConstInt(LLVMInt32Type(), 0, 1), CurrentCounter };
  LLVMValueRef Elem = LLVMBuildInBoundsGEP(Builder, ArrayVal, ElemIdx, 2, "");
  copyMemory(Elem, TheValue, getSConstInt(Size)); 
  LLVMBuildBr(Builder, InitBB);

  LLVMPositionBuilderAtEnd(Builder, EndBB);
  return ArrayVal;
}
예제 #4
0
/* TargetMachine.t -> DataLayout.t */
CAMLprim value llvm_targetmachine_data_layout(value Machine) {
  CAMLparam1(Machine);
  CAMLlocal1(DataLayout);

  /* LLVMGetTargetMachineData returns a pointer owned by the TargetMachine,
     so it is impossible to wrap it with llvm_alloc_target_data, which assumes
     that OCaml owns the pointer. */
  LLVMTargetDataRef OrigDataLayout;
  OrigDataLayout = LLVMGetTargetMachineData(TargetMachine_val(Machine));

  char* TargetDataCStr;
  TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout);
  DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr));
  LLVMDisposeMessage(TargetDataCStr);

  CAMLreturn(DataLayout);
}
/* string -> TargetData.t */
CAMLprim LLVMTargetDataRef llvm_targetdata_create(value StringRep) {
    return LLVMCreateTargetData(String_val(StringRep));
}
예제 #6
0
/* string -> DataLayout.t */
CAMLprim value llvm_datalayout_of_string(value StringRep) {
  return llvm_alloc_data_layout(LLVMCreateTargetData(String_val(StringRep)));
}
/**
 * Allocate gallivm LLVM objects.
 * \return  TRUE for success, FALSE for failure
 */
static boolean
init_gallivm_state(struct gallivm_state *gallivm)
{
   assert(!gallivm->context);
   assert(!gallivm->module);
   assert(!gallivm->provider);

   lp_build_init();

   if (!gallivm_context) {
      gallivm_context = LLVMContextCreate();
   }
   gallivm->context = gallivm_context;
   if (!gallivm->context)
      goto fail;

   gallivm->module = LLVMModuleCreateWithNameInContext("gallivm",
                                                       gallivm->context);
   if (!gallivm->module)
      goto fail;

   gallivm->provider =
      LLVMCreateModuleProviderForExistingModule(gallivm->module);
   if (!gallivm->provider)
      goto fail;

   gallivm->builder = LLVMCreateBuilderInContext(gallivm->context);
   if (!gallivm->builder)
      goto fail;

   /* FIXME: MC-JIT only allows compiling one module at a time, and it must be
    * complete when MC-JIT is created. So defer the MC-JIT engine creation for
    * now.
    */
#if !USE_MCJIT
   if (!init_gallivm_engine(gallivm)) {
      goto fail;
   }
#else
   /*
    * MC-JIT engine compiles the module immediately on creation, so we can't
    * obtain the target data from it.  Instead we create a target data layout
    * from a string.
    *
    * The produced layout strings are not precisely the same, but should make
    * no difference for the kind of optimization passes we run.
    *
    * For reference this is the layout string on x64:
    *
    *   e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64
    *
    * See also:
    * - http://llvm.org/docs/LangRef.html#datalayout
    */

   {
      const unsigned pointer_size = 8 * sizeof(void *);
      char layout[512];
      util_snprintf(layout, sizeof layout, "%c-p:%u:%u:%u-i64:64:64-a0:0:%u-s0:%u:%u",
#ifdef PIPE_ARCH_LITTLE_ENDIAN
                    'e', // little endian
#else
                    'E', // big endian
#endif
                    pointer_size, pointer_size, pointer_size, // pointer size, abi alignment, preferred alignment
                    pointer_size, // aggregate preferred alignment
                    pointer_size, pointer_size); // stack objects abi alignment, preferred alignment

      gallivm->target = LLVMCreateTargetData(layout);
      if (!gallivm->target) {
         return FALSE;
      }
   }
#endif

   if (!create_pass_manager(gallivm))
      goto fail;

   return TRUE;

fail:
   free_gallivm_state(gallivm);
   return FALSE;
}