Пример #1
0
void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
  // Check to see if this is a special global used by LLVM, if so, emit it.
  if (!GV->hasInitializer() ||
      EmitSpecialLLVMGlobal(GV))
    return;

  const TargetData *TD = TM.getTargetData();
  OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM));

  
  MCSymbol *GVSym = Mang->getSymbol(GV);
  Constant *C = GV->getInitializer();
  unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType());
  
  // Mark the start of the global
  OutStreamer.EmitRawText("\t.cc_top " + Twine(GVSym->getName()) + ".data," +
                          GVSym->getName());

  switch (GV->getLinkage()) {
  case GlobalValue::AppendingLinkage:
    report_fatal_error("AppendingLinkage is not supported by this target!");
  case GlobalValue::LinkOnceAnyLinkage:
  case GlobalValue::LinkOnceODRLinkage:
  case GlobalValue::WeakAnyLinkage:
  case GlobalValue::WeakODRLinkage:
  case GlobalValue::ExternalLinkage:
    emitArrayBound(GVSym, GV);
    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);

    // TODO Use COMDAT groups for LinkOnceLinkage
    if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())
      OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
    // FALL THROUGH
  case GlobalValue::InternalLinkage:
  case GlobalValue::PrivateLinkage:
  case GlobalValue::LinkerPrivateLinkage:
    break;
  case GlobalValue::DLLImportLinkage:
    llvm_unreachable("DLLImport linkage is not supported by this target!");
  case GlobalValue::DLLExportLinkage:
    llvm_unreachable("DLLExport linkage is not supported by this target!");
  default:
    llvm_unreachable("Unknown linkage type!");
  }

  EmitAlignment(Align > 2 ? Align : 2, GV);
  
  unsigned Size = TD->getTypeAllocSize(C->getType());
  if (GV->isThreadLocal()) {
    Size *= MaxThreads;
  }
  if (MAI->hasDotTypeDotSizeDirective()) {
    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject);
    OutStreamer.EmitRawText("\t.size " + Twine(GVSym->getName()) + "," +
                            Twine(Size));
  }
  OutStreamer.EmitLabel(GVSym);
  
  EmitGlobalConstant(C);
  if (GV->isThreadLocal()) {
    for (unsigned i = 1; i < MaxThreads; ++i)
      EmitGlobalConstant(C);
  }
  // The ABI requires that unsigned scalar types smaller than 32 bits
  // are padded to 32 bits.
  if (Size < 4)
    OutStreamer.EmitZeros(4 - Size, 0);
  
  // Mark the end of the global
  OutStreamer.EmitRawText("\t.cc_bottom " + Twine(GVSym->getName()) + ".data");
}
// llvm_asm_file_end - Finish the .s file.
void llvm_asm_file_end(void) {
  timevar_push(TV_LLVM_PERFILE);
  llvm_shutdown_obj X;  // Call llvm_shutdown() on exit.

  if (flag_pch_file) {
    writeLLVMTypesStringTable();
    writeLLVMValues();
  }

  // Add an llvm.global_ctors global if needed.
  if (!StaticCtors.empty())
    CreateStructorsList(StaticCtors, "llvm.global_ctors");
  // Add an llvm.global_dtors global if needed.
  if (!StaticDtors.empty())
    CreateStructorsList(StaticDtors, "llvm.global_dtors");
  
  if (!AttributeUsedGlobals.empty()) {
    const Type *SBP = PointerType::get(Type::Int8Ty);
    ArrayType *AT = ArrayType::get(SBP, AttributeUsedGlobals.size());
    Constant *Init = ConstantArray::get(AT, AttributeUsedGlobals);
    GlobalValue* gv = new GlobalVariable(AT, false, 
                       GlobalValue::AppendingLinkage, Init,
                       "llvm.used", TheModule);
    gv->setSection("llvm.metadata");
    AttributeUsedGlobals.clear();
  }
  
  // Add llvm.noinline
  if (!AttributeNoinlineFunctions.empty()) {
    const Type *SBP= PointerType::get(Type::Int8Ty);
    ArrayType *AT = ArrayType::get(SBP, AttributeNoinlineFunctions.size());
    Constant *Init = ConstantArray::get(AT, AttributeNoinlineFunctions);
    GlobalValue *gv = new GlobalVariable(AT, false, 
                                        GlobalValue::AppendingLinkage, Init,
                                        "llvm.noinline", TheModule);
    gv->setSection("llvm.metadata");
    
    // Clear vector
    AttributeNoinlineFunctions.clear();
  }
  
  // Add llvm.global.annotations
  if (!AttributeAnnotateGlobals.empty()) {
    
    Constant *Array =
    ConstantArray::get(ArrayType::get(AttributeAnnotateGlobals[0]->getType(), 
                                      AttributeAnnotateGlobals.size()),
                       AttributeAnnotateGlobals);
    GlobalValue *gv = new GlobalVariable(Array->getType(), false, 
                                         GlobalValue::AppendingLinkage, Array, 
                                         "llvm.global.annotations", TheModule); 
    gv->setSection("llvm.metadata");
    AttributeAnnotateGlobals.clear();
  
  }
  
  // Finish off the per-function pass.
  if (PerFunctionPasses)
    PerFunctionPasses->doFinalization();
    
  // Run module-level optimizers, if any are present.
  if (PerModulePasses)
    PerModulePasses->run(*TheModule);
  
  // Run the code generator, if present.
  if (CodeGenPasses) {
    CodeGenPasses->doInitialization();
    for (Module::iterator I = TheModule->begin(), E = TheModule->end();
         I != E; ++I)
      if (!I->isDeclaration())
        CodeGenPasses->run(*I);
    CodeGenPasses->doFinalization();
  }

  AsmOutStream->flush();
  fflush(asm_out_file);
  delete AsmOutStream;
  AsmOutStream = 0;
  delete AsmOutFile;
  AsmOutFile = 0;
  timevar_pop(TV_LLVM_PERFILE);
}
/// emit_global_to_llvm - Emit the specified VAR_DECL or aggregate CONST_DECL to
/// LLVM as a global variable.  This function implements the end of
/// assemble_variable.
void emit_global_to_llvm(tree decl) {
  if (errorcount || sorrycount) return;

  // FIXME: Support alignment on globals: DECL_ALIGN.
  // FIXME: DECL_PRESERVE_P indicates the var is marked with attribute 'used'.

  // Global register variables don't turn into LLVM GlobalVariables.
  if (TREE_CODE(decl) == VAR_DECL && DECL_REGISTER(decl))
    return;

  timevar_push(TV_LLVM_GLOBALS);

  // Get or create the global variable now.
  GlobalVariable *GV = cast<GlobalVariable>(DECL_LLVM(decl));
  
  // Convert the initializer over.
  Constant *Init;
  if (DECL_INITIAL(decl) == 0 || DECL_INITIAL(decl) == error_mark_node) {
    // This global should be zero initialized.  Reconvert the type in case the
    // forward def of the global and the real def differ in type (e.g. declared
    // as 'int A[]', and defined as 'int A[100]').
    Init = Constant::getNullValue(ConvertType(TREE_TYPE(decl)));
  } else {
    assert((TREE_CONSTANT(DECL_INITIAL(decl)) || 
            TREE_CODE(DECL_INITIAL(decl)) == STRING_CST) &&
           "Global initializer should be constant!");
    
    // Temporarily set an initializer for the global, so we don't infinitely
    // recurse.  If we don't do this, we can hit cases where we see "oh a global
    // with an initializer hasn't been initialized yet, call emit_global_to_llvm
    // on it".  When constructing the initializer it might refer to itself.
    // this can happen for things like void *G = &G;
    //
    GV->setInitializer(UndefValue::get(GV->getType()->getElementType()));
    Init = TreeConstantToLLVM::Convert(DECL_INITIAL(decl));
  }

  // If we had a forward definition that has a type that disagrees with our
  // initializer, insert a cast now.  This sort of thing occurs when we have a
  // global union, and the LLVM type followed a union initializer that is
  // different from the union element used for the type.
  if (GV->getType()->getElementType() != Init->getType()) {
    GV->removeFromParent();
    GlobalVariable *NGV = new GlobalVariable(Init->getType(), GV->isConstant(),
                                             GlobalValue::ExternalLinkage, 0,
                                             GV->getName(), TheModule);
    GV->replaceAllUsesWith(ConstantExpr::getBitCast(NGV, GV->getType()));
    delete GV;
    SET_DECL_LLVM(decl, NGV);
    GV = NGV;
  }
 
  // Set the initializer.
  GV->setInitializer(Init);

  // Set thread local (TLS)
  if (TREE_CODE(decl) == VAR_DECL && DECL_THREAD_LOCAL(decl))
    GV->setThreadLocal(true);

  // Set the linkage.
  if (!TREE_PUBLIC(decl)) {
    GV->setLinkage(GlobalValue::InternalLinkage);
  } else if (DECL_WEAK(decl) || DECL_ONE_ONLY(decl) ||
             (DECL_COMMON(decl) &&  // DECL_COMMON is only meaningful if no init
              (!DECL_INITIAL(decl) || DECL_INITIAL(decl) == error_mark_node))) {
    // llvm-gcc also includes DECL_VIRTUAL_P here.
    GV->setLinkage(GlobalValue::WeakLinkage);
  } else if (DECL_COMDAT(decl)) {
    GV->setLinkage(GlobalValue::LinkOnceLinkage);
  }

#ifdef TARGET_ADJUST_LLVM_LINKAGE
  TARGET_ADJUST_LLVM_LINKAGE(GV,decl);
#endif /* TARGET_ADJUST_LLVM_LINKAGE */

  // Handle visibility style
  if (TREE_PUBLIC(decl)) {
    if (DECL_VISIBILITY(decl) == VISIBILITY_HIDDEN)
      GV->setVisibility(GlobalValue::HiddenVisibility);
    else if (DECL_VISIBILITY(decl) == VISIBILITY_PROTECTED)
      GV->setVisibility(GlobalValue::ProtectedVisibility);
  }

  // Set the section for the global.
  if (TREE_CODE(decl) == VAR_DECL || TREE_CODE(decl) == CONST_DECL) {
    if (DECL_SECTION_NAME(decl)) {
      GV->setSection(TREE_STRING_POINTER(DECL_SECTION_NAME(decl)));
#ifdef LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION
    } else if (const char *Section = 
                LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION(decl)) {
      GV->setSection(Section);
#endif
    }
    
    // Set the alignment for the global if one of the following condition is met
    // 1) DECL_ALIGN_UNIT does not match alignment as per ABI specification
    // 2) DECL_ALIGN is set by user.
    if (DECL_ALIGN_UNIT(decl)) {
      unsigned TargetAlign = getTargetData().getABITypeAlignment(GV->getType()->getElementType());
      if (DECL_USER_ALIGN(decl) || TargetAlign != DECL_ALIGN_UNIT(decl))
        GV->setAlignment(DECL_ALIGN_UNIT(decl));
    }

    // Handle used decls
    if (DECL_PRESERVE_P (decl)) {
      const Type *SBP= PointerType::get(Type::Int8Ty);
      AttributeUsedGlobals.push_back(ConstantExpr::getBitCast(GV, SBP));
    }
  
    // Add annotate attributes for globals
    if (DECL_ATTRIBUTES(decl))
      AddAnnotateAttrsToGlobal(GV, decl);
  }
  
  if (TheDebugInfo) TheDebugInfo->EmitGlobalVariable(GV, decl); 
  
  timevar_pop(TV_LLVM_GLOBALS);
}
Пример #4
0
bool SanitizerCoverageModule::runOnModule(Module &M) {
  if (Options.CoverageType == SanitizerCoverageOptions::SCK_None)
    return false;
  C = &(M.getContext());
  DL = &M.getDataLayout();
  CurModule = &M;
  IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
  Type *VoidTy = Type::getVoidTy(*C);
  IRBuilder<> IRB(*C);
  Type *Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
  Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
  Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty());
  Int64Ty = IRB.getInt64Ty();

  SanCovFunction = checkSanitizerInterfaceFunction(
      M.getOrInsertFunction(kSanCovName, VoidTy, Int32PtrTy, nullptr));
  SanCovWithCheckFunction = checkSanitizerInterfaceFunction(
      M.getOrInsertFunction(kSanCovWithCheckName, VoidTy, Int32PtrTy, nullptr));
  SanCovIndirCallFunction =
      checkSanitizerInterfaceFunction(M.getOrInsertFunction(
          kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr));
  SanCovTraceCmpFunction =
      checkSanitizerInterfaceFunction(M.getOrInsertFunction(
          kSanCovTraceCmp, VoidTy, Int64Ty, Int64Ty, Int64Ty, nullptr));
  SanCovTraceSwitchFunction =
      checkSanitizerInterfaceFunction(M.getOrInsertFunction(
          kSanCovTraceSwitch, VoidTy, Int64Ty, Int64PtrTy, nullptr));

  // We insert an empty inline asm after cov callbacks to avoid callback merge.
  EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
                            StringRef(""), StringRef(""),
                            /*hasSideEffects=*/true);

  SanCovTraceEnter = checkSanitizerInterfaceFunction(
      M.getOrInsertFunction(kSanCovTraceEnter, VoidTy, Int32PtrTy, nullptr));
  SanCovTraceBB = checkSanitizerInterfaceFunction(
      M.getOrInsertFunction(kSanCovTraceBB, VoidTy, Int32PtrTy, nullptr));

  // At this point we create a dummy array of guards because we don't
  // know how many elements we will need.
  Type *Int32Ty = IRB.getInt32Ty();
  Type *Int8Ty = IRB.getInt8Ty();

  GuardArray =
      new GlobalVariable(M, Int32Ty, false, GlobalValue::ExternalLinkage,
                         nullptr, "__sancov_gen_cov_tmp");
  if (Options.Use8bitCounters)
    EightBitCounterArray =
        new GlobalVariable(M, Int8Ty, false, GlobalVariable::ExternalLinkage,
                           nullptr, "__sancov_gen_cov_tmp");

  for (auto &F : M)
    runOnFunction(F);

  auto N = NumberOfInstrumentedBlocks();

  // Now we know how many elements we need. Create an array of guards
  // with one extra element at the beginning for the size.
  Type *Int32ArrayNTy = ArrayType::get(Int32Ty, N + 1);
  GlobalVariable *RealGuardArray = new GlobalVariable(
      M, Int32ArrayNTy, false, GlobalValue::PrivateLinkage,
      Constant::getNullValue(Int32ArrayNTy), "__sancov_gen_cov");


  // Replace the dummy array with the real one.
  GuardArray->replaceAllUsesWith(
      IRB.CreatePointerCast(RealGuardArray, Int32PtrTy));
  GuardArray->eraseFromParent();

  GlobalVariable *RealEightBitCounterArray;
  if (Options.Use8bitCounters) {
    // Make sure the array is 16-aligned.
    static const int kCounterAlignment = 16;
    Type *Int8ArrayNTy =
        ArrayType::get(Int8Ty, RoundUpToAlignment(N, kCounterAlignment));
    RealEightBitCounterArray = new GlobalVariable(
        M, Int8ArrayNTy, false, GlobalValue::PrivateLinkage,
        Constant::getNullValue(Int8ArrayNTy), "__sancov_gen_cov_counter");
    RealEightBitCounterArray->setAlignment(kCounterAlignment);
    EightBitCounterArray->replaceAllUsesWith(
        IRB.CreatePointerCast(RealEightBitCounterArray, Int8PtrTy));
    EightBitCounterArray->eraseFromParent();
  }

  // Create variable for module (compilation unit) name
  Constant *ModNameStrConst =
      ConstantDataArray::getString(M.getContext(), M.getName(), true);
  GlobalVariable *ModuleName =
      new GlobalVariable(M, ModNameStrConst->getType(), true,
                         GlobalValue::PrivateLinkage, ModNameStrConst);

  Function *CtorFunc;
  std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
      M, kSanCovModuleCtorName, kSanCovModuleInitName,
      {Int32PtrTy, IntptrTy, Int8PtrTy, Int8PtrTy},
      {IRB.CreatePointerCast(RealGuardArray, Int32PtrTy),
       ConstantInt::get(IntptrTy, N),
       Options.Use8bitCounters
           ? IRB.CreatePointerCast(RealEightBitCounterArray, Int8PtrTy)
           : Constant::getNullValue(Int8PtrTy),
       IRB.CreatePointerCast(ModuleName, Int8PtrTy)});

  appendToGlobalCtors(M, CtorFunc, kSanCtorAndDtorPriority);

  return true;
}
Пример #5
0
void jl_dump_native(const char *bc_fname, const char *unopt_bc_fname, const char *obj_fname, const char *sysimg_data, size_t sysimg_len)
{
    JL_TIMING(NATIVE_DUMP);
    // We don't want to use MCJIT's target machine because
    // it uses the large code model and we may potentially
    // want less optimizations there.
    Triple TheTriple = Triple(jl_TargetMachine->getTargetTriple());
    // make sure to emit the native object format, even if FORCE_ELF was set in codegen
#if defined(_OS_WINDOWS_)
    TheTriple.setObjectFormat(Triple::COFF);
#elif defined(_OS_DARWIN_)
    TheTriple.setObjectFormat(Triple::MachO);
    TheTriple.setOS(llvm::Triple::MacOSX);
#endif
    std::unique_ptr<TargetMachine>
    TM(jl_TargetMachine->getTarget().createTargetMachine(
        TheTriple.getTriple(),
        jl_TargetMachine->getTargetCPU(),
        jl_TargetMachine->getTargetFeatureString(),
        jl_TargetMachine->Options,
#if defined(_OS_LINUX_) || defined(_OS_FREEBSD_)
        Reloc::PIC_,
#else
        Optional<Reloc::Model>(),
#endif
#if defined(_CPU_PPC_) || defined(_CPU_PPC64_)
        // On PPC the small model is limited to 16bit offsets
        CodeModel::Medium,
#else
        // Use small model so that we can use signed 32bits offset in the function and GV tables
        CodeModel::Small,
#endif
        CodeGenOpt::Aggressive // -O3 TODO: respect command -O0 flag?
        ));

    legacy::PassManager PM;
    addTargetPasses(&PM, TM.get());

    // set up optimization passes
    SmallVector<char, 128> bc_Buffer;
    SmallVector<char, 128> obj_Buffer;
    SmallVector<char, 128> unopt_bc_Buffer;
    raw_svector_ostream bc_OS(bc_Buffer);
    raw_svector_ostream obj_OS(obj_Buffer);
    raw_svector_ostream unopt_bc_OS(unopt_bc_Buffer);
    std::vector<NewArchiveMember> bc_Archive;
    std::vector<NewArchiveMember> obj_Archive;
    std::vector<NewArchiveMember> unopt_bc_Archive;
    std::vector<std::string> outputs;

    if (unopt_bc_fname)
        PM.add(createBitcodeWriterPass(unopt_bc_OS));
    if (bc_fname || obj_fname)
        addOptimizationPasses(&PM, jl_options.opt_level, true);
    if (bc_fname)
        PM.add(createBitcodeWriterPass(bc_OS));
    if (obj_fname)
        if (TM->addPassesToEmitFile(PM, obj_OS, TargetMachine::CGFT_ObjectFile, false))
            jl_safe_printf("ERROR: target does not support generation of object files\n");

    // Reset the target triple to make sure it matches the new target machine
    shadow_output->setTargetTriple(TM->getTargetTriple().str());
#if JL_LLVM_VERSION >= 40000
    DataLayout DL = TM->createDataLayout();
    DL.reset(DL.getStringRepresentation() + "-ni:10:11:12");
    shadow_output->setDataLayout(DL);
#else
    shadow_output->setDataLayout(TM->createDataLayout());
#endif

    // add metadata information
    if (imaging_mode) {
        emit_offset_table(shadow_output, jl_sysimg_gvars, "jl_sysimg_gvars");
        emit_offset_table(shadow_output, jl_sysimg_fvars, "jl_sysimg_fvars");

        // reflect the address of the jl_RTLD_DEFAULT_handle variable
        // back to the caller, so that we can check for consistency issues
        GlobalValue *jlRTLD_DEFAULT_var = shadow_output->getNamedValue("jl_RTLD_DEFAULT_handle");
        addComdat(new GlobalVariable(*shadow_output,
                                     jlRTLD_DEFAULT_var->getType(),
                                     true,
                                     GlobalVariable::ExternalLinkage,
                                     jlRTLD_DEFAULT_var,
                                     "jl_RTLD_DEFAULT_handle_pointer"));
    }

    // do the actual work
    auto add_output = [&] (Module &M, StringRef unopt_bc_Name, StringRef bc_Name, StringRef obj_Name) {
        PM.run(M);
        if (unopt_bc_fname)
            emit_result(unopt_bc_Archive, unopt_bc_Buffer, unopt_bc_Name, outputs);
        if (bc_fname)
            emit_result(bc_Archive, bc_Buffer, bc_Name, outputs);
        if (obj_fname)
            emit_result(obj_Archive, obj_Buffer, obj_Name, outputs);
    };

    add_output(*shadow_output, "unopt.bc", "text.bc", "text.o");

    LLVMContext &Context = shadow_output->getContext();
    std::unique_ptr<Module> sysimage(new Module("sysimage", Context));
    sysimage->setTargetTriple(shadow_output->getTargetTriple());
    sysimage->setDataLayout(shadow_output->getDataLayout());

    addComdat(new GlobalVariable(*sysimage,
                                 T_size,
                                 true,
                                 GlobalVariable::ExternalLinkage,
                                 ConstantInt::get(T_size, globalUnique + 1),
                                 "jl_globalUnique"));

    if (sysimg_data) {
        Constant *data = ConstantDataArray::get(Context,
            ArrayRef<uint8_t>((const unsigned char*)sysimg_data, sysimg_len));
        addComdat(new GlobalVariable(*sysimage, data->getType(), false,
                                     GlobalVariable::ExternalLinkage,
                                     data, "jl_system_image_data"))->setAlignment(64);
        Constant *len = ConstantInt::get(T_size, sysimg_len);
        addComdat(new GlobalVariable(*sysimage, len->getType(), true,
                                     GlobalVariable::ExternalLinkage,
                                     len, "jl_system_image_size"));
    }
    add_output(*sysimage, "data.bc", "data.bc", "data.o");

    object::Archive::Kind Kind = getDefaultForHost(TheTriple);
    if (unopt_bc_fname)
        handleAllErrors(writeArchive(unopt_bc_fname, unopt_bc_Archive, true,
                    Kind, true, false), reportWriterError);
    if (bc_fname)
        handleAllErrors(writeArchive(bc_fname, bc_Archive, true,
                    Kind, true, false), reportWriterError);
    if (obj_fname)
        handleAllErrors(writeArchive(obj_fname, obj_Archive, true,
                    Kind, true, false), reportWriterError);

    imaging_mode = false;
}
Пример #6
0
/// Replace direct callers of Old with New. Also add parameters to the call to
/// \p New, which are defined by the FuncIdx's value in \p Params.
bool SwiftMergeFunctions::replaceDirectCallers(Function *Old, Function *New,
                                   const ParamInfos &Params, unsigned FuncIdx) {
  bool AllReplaced = true;

  SmallVector<CallInst *, 8> Callers;
  
  for (Use &U : Old->uses()) {
    auto *I = dyn_cast<Instruction>(U.getUser());
    if (!I) {
      AllReplaced = false;
      continue;
    }
    FunctionEntry *FE = getEntry(I->getFunction());
    if (FE)
      removeEquivalenceClassFromTree(FE);
    
    auto *CI = dyn_cast<CallInst>(I);
    if (!CI || CI->getCalledValue() != Old) {
      AllReplaced = false;
      continue;
    }
    Callers.push_back(CI);
  }
  if (!AllReplaced)
    return false;

  for (CallInst *CI : Callers) {
    auto &Context = New->getContext();
    auto NewPAL = New->getAttributes();

    SmallVector<Type *, 8> OldParamTypes;
    SmallVector<Value *, 16> NewArgs;
    SmallVector<AttributeSet, 8> NewArgAttrs;
    IRBuilder<> Builder(CI);

    FunctionType *NewFuncTy = New->getFunctionType();
    (void) NewFuncTy;
    unsigned ParamIdx = 0;
    
    // Add the existing parameters.
    for (Value *OldArg : CI->arg_operands()) {
      NewArgAttrs.push_back(NewPAL.getParamAttributes(ParamIdx));
      NewArgs.push_back(OldArg);
      OldParamTypes.push_back(OldArg->getType());
      ++ParamIdx;
    }
    // Add the new parameters.
    for (const ParamInfo &PI : Params) {
      assert(ParamIdx < NewFuncTy->getNumParams());
      Constant *ArgValue = PI.Values[FuncIdx];
      assert(ArgValue != Old &&
        "should not try to replace all callers of self referencing functions");
      NewArgs.push_back(ArgValue);
      OldParamTypes.push_back(ArgValue->getType());
      ++ParamIdx;
    }

    auto *FType = FunctionType::get(Old->getFunctionType()->getReturnType(),
                                    OldParamTypes, false);
    auto *FPtrType = PointerType::get(FType,
                        cast<PointerType>(New->getType())->getAddressSpace());

    Value *Callee = ConstantExpr::getBitCast(New, FPtrType);
    CallInst *NewCI = Builder.CreateCall(Callee, NewArgs);
    NewCI->setCallingConv(CI->getCallingConv());
    // Don't transfer attributes from the function to the callee. Function
    // attributes typically aren't relevant to the calling convention or ABI.
    NewCI->setAttributes(AttributeList::get(Context, /*FnAttrs=*/AttributeSet(),
                                            NewPAL.getRetAttributes(),
                                            NewArgAttrs));
    CI->replaceAllUsesWith(NewCI);
    CI->eraseFromParent();
  }
  assert(Old->use_empty() && "should have replaced all uses of old function");
  return Old->hasLocalLinkage();
}
Пример #7
0
ConstantExpression::ConstantExpression(Constant constant) :
        constant { constant }
{
    auto type = constant.getType();
    setType(*type);
}
Пример #8
0
// Create a constant for Str so that we can pass it to the run-time lib.
static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str) {
  Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
  return new GlobalVariable(M, StrConst->getType(), true,
                            GlobalValue::PrivateLinkage, StrConst, "");
}
Пример #9
0
bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
                          Module &M, bool isConst, unsigned AddrSpace) const {
  const TargetLowering *TLI = TM->getTargetLowering();
  const DataLayout *DL = TLI->getDataLayout();

  // FIXME: Infer the maximum possible offset depending on the actual users
  // (these max offsets are different for the users inside Thumb or ARM
  // functions)
  unsigned MaxOffset = TLI->getMaximalGlobalOffset();

  // FIXME: Find better heuristics
  std::stable_sort(Globals.begin(), Globals.end(),
                   [DL](const GlobalVariable *GV1, const GlobalVariable *GV2) {
    Type *Ty1 = cast<PointerType>(GV1->getType())->getElementType();
    Type *Ty2 = cast<PointerType>(GV2->getType())->getElementType();

    return (DL->getTypeAllocSize(Ty1) < DL->getTypeAllocSize(Ty2));
  });

  Type *Int32Ty = Type::getInt32Ty(M.getContext());

  assert(Globals.size() > 1);

  // FIXME: This simple solution merges globals all together as maximum as
  // possible. However, with this solution it would be hard to remove dead
  // global symbols at link-time. An alternative solution could be checking
  // global symbols references function by function, and make the symbols
  // being referred in the same function merged and we would probably need
  // to introduce heuristic algorithm to solve the merge conflict from
  // different functions.
  for (size_t i = 0, e = Globals.size(); i != e; ) {
    size_t j = 0;
    uint64_t MergedSize = 0;
    std::vector<Type*> Tys;
    std::vector<Constant*> Inits;

    bool HasExternal = false;
    GlobalVariable *TheFirstExternal = 0;
    for (j = i; j != e; ++j) {
      Type *Ty = Globals[j]->getType()->getElementType();
      MergedSize += DL->getTypeAllocSize(Ty);
      if (MergedSize > MaxOffset) {
        break;
      }
      Tys.push_back(Ty);
      Inits.push_back(Globals[j]->getInitializer());

      if (Globals[j]->hasExternalLinkage() && !HasExternal) {
        HasExternal = true;
        TheFirstExternal = Globals[j];
      }
    }

    // If merged variables doesn't have external linkage, we needn't to expose
    // the symbol after merging.
    GlobalValue::LinkageTypes Linkage = HasExternal
                                            ? GlobalValue::ExternalLinkage
                                            : GlobalValue::InternalLinkage;

    // If merged variables have external linkage, we use symbol name of the
    // first variable merged as the suffix of global symbol name. This would
    // be able to avoid the link-time naming conflict for globalm symbols.
    Twine MergedGVName = HasExternal
                             ? "_MergedGlobals_" + TheFirstExternal->getName()
                             : "_MergedGlobals";

    StructType *MergedTy = StructType::get(M.getContext(), Tys);
    Constant *MergedInit = ConstantStruct::get(MergedTy, Inits);

    GlobalVariable *MergedGV = new GlobalVariable(
        M, MergedTy, isConst, Linkage, MergedInit, MergedGVName, nullptr,
        GlobalVariable::NotThreadLocal, AddrSpace);

    for (size_t k = i; k < j; ++k) {
      GlobalValue::LinkageTypes Linkage = Globals[k]->getLinkage();
      std::string Name = Globals[k]->getName();

      Constant *Idx[2] = {
        ConstantInt::get(Int32Ty, 0),
        ConstantInt::get(Int32Ty, k-i)
      };
      Constant *GEP = ConstantExpr::getInBoundsGetElementPtr(MergedGV, Idx);
      Globals[k]->replaceAllUsesWith(GEP);
      Globals[k]->eraseFromParent();

      if (Linkage != GlobalValue::InternalLinkage) {
        // Generate a new alias...
        auto *PTy = cast<PointerType>(GEP->getType());
        GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(),
                            Linkage, Name, GEP, &M);
      }

      NumMerged++;
    }
    i = j;
  }

  return true;
}
Пример #10
0
bool ProfilingPass::doInitialization(Module &M)
{
	LLVMContext& context = M.getContext();
	Function* mainFunc = M.getFunction("main");
	const string moduleName = M.getModuleIdentifier();
	if (mainFunc!=NULL) {
		//BasicBlock* entryBlock = &mainFunc->front();
		Constant* Init = ConstantArray::get(context,moduleName,true);	// Convert it to an LLVM Type
		GlobalVariable* nameStr = new GlobalVariable(Init->getType(), true, GlobalValue::InternalLinkage, Init, "NameStr" );
		M.getGlobalList().push_back( nameStr );						// Insert it into the list of globals for module
		std::vector<Constant*>IndicesC(2);
		IndicesC[0] = Constant::getNullValue(Type::getInt32Ty(context));
		IndicesC[1] = ConstantInt::get(Type::getInt32Ty(context),0);
		Constant *getElemExpr =  ConstantExpr::getGetElementPtr(nameStr, &IndicesC[0], IndicesC.size());
		vector<Value*> initInjectArgs;
		initInjectArgs.push_back( getElemExpr ); 
		FunctionType* initInjectionFuncType = FunctionType::get(Type::getVoidTy(context), 
		vector<const Type*>(1,  PointerType::get(Type::getInt8Ty(context),0)),0); 
		
		//BasicBlock *exitBlock = &mainFunc->back();
		Instruction *I;
		for (inst_iterator fi = inst_begin(mainFunc), fe = inst_end(mainFunc); fi!=fe; ++fi){
			I = &*fi;
			if(isa<ReturnInst>(I))
				break;
		}
		BasicBlock *retblock = I->getParent(); //*retpred = retblock->getSinglePredecessor();
		
		Instruction *term = retblock->getTerminator();
		Constant *endFunc = M.getOrInsertFunction("endProfiling", initInjectionFuncType);
		vector<Value*> countArgs(1);
		//const IntegerType* itype = IntegerType::get(context,32);
		//Value* branchVal = ConstantInt::get(itype, BRANCH );
		CallInst::Create(endFunc, initInjectArgs.begin(), initInjectArgs.end(), "", term);
	}
	else
	{
		Constant* Init = ConstantArray::get(context,moduleName,true);	// Convert it to an LLVM Type
		GlobalVariable* nameStr = new GlobalVariable(Init->getType(), true, GlobalValue::InternalLinkage, Init, "NameStr" );
		M.getGlobalList().push_back( nameStr );
	}

	//***********************************************************************************************************
	//code for loading configure file should be here
	ifstream config ("llfi_configure.txt");
	if (config.is_open())
	{
		// we need to extract information from config file here Qining
		// this loop is used to know if the file is end
		while ( config.good() )
    	{
    		string line;
      		getline (config,line);
      		if(line.empty())	continue;
      		//if the line is empty, just skip.
      		//Any block of configure is started with one specific function
      		unsigned found = line.find("FUNCTION_NAME:");
      		if (found < line.length())
      		{
    			//std::cout << "\nfound FUNCTION_NAME at " << found << '\n';
    			std::string func_name = line.substr (found + string("FUNCTION_NAME:").length(),line.length() - found - string("FUNCTION_NAME:").length());
    			//first, I need to trim it
    			while(func_name[0] == ' ')
    			{
    				func_name.erase(0, 1);
    			}
    			while(func_name[func_name.length() - 1] == ' ')
    			{
    				func_name.erase(func_name.length() - 1, 0);
    			}
    			//so now I've got the name of the function
    			if(func_name.empty())	continue;
				std::cout << "The func_name is " << func_name << "\n";
				map_func_argu[func_name] = set<unsigned int>(); // create entry
				//map_func_fault_type[func_name] = set<unsigned int>(); 
				//second, I need to load argument set and type set
				do
				{
					line.clear();
					getline(config,line); // get the next line
					if(!config.good())	break; // if the new line is the end of file, our job is done.
					if(line.find("ARGUMENT:") < line.length())
					{
						//insert argument id to argument set
						std::string arg_set = line.substr(line.find("ARGUMENT:")+string("ARGUMENT:").length(), line.length() - line.find("ARGUMENT:")-string("ARGUMENT:").length());
						std::string arg;
						while(!arg_set.empty())
						{
							while(arg_set[0] <= '9' && arg_set[0] >= '0')
							{
								arg.append(arg_set.substr(0,1));
								if(!arg_set.empty())	arg_set.erase(0,1);
							}
							if(!arg.empty())
							{
								unsigned int arg_num = atoi(arg.c_str()) - 1;
								map_func_argu[func_name].insert(arg_num);
								std::cout << "\tinclude arg: " << arg_num+1 << "\n";
							}
							arg.clear();
							if(!arg_set.empty())	arg_set.erase(0,1);

						}
					}

				}while(line.find("FUNC_DEF_END") != 0);

    		}

    	}
    	// The file is end, we should have already finished our work, now close the file
    	config.close();
	}
	else errs()<<"Unable to open config file, use default config: all instructions, one bit flip\n";
	//***********************************************************************************************************

     return FunctionPass::doInitialization(M);
}
Пример #11
0
bool SanitizerCoverageModule::runOnModule(Module &M) {
  if (Options.CoverageType == SanitizerCoverageOptions::SCK_None)
    return false;
  C = &(M.getContext());
  DL = &M.getDataLayout();
  CurModule = &M;
  TargetTriple = Triple(M.getTargetTriple());
  HasSancovGuardsSection = false;
  IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
  IntptrPtrTy = PointerType::getUnqual(IntptrTy);
  Type *VoidTy = Type::getVoidTy(*C);
  IRBuilder<> IRB(*C);
  Type *Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
  Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty());
  Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
  Int64Ty = IRB.getInt64Ty();
  Int32Ty = IRB.getInt32Ty();

  SanCovFunction = checkSanitizerInterfaceFunction(
      M.getOrInsertFunction(SanCovName, VoidTy, Int32PtrTy, nullptr));
  SanCovWithCheckFunction = checkSanitizerInterfaceFunction(
      M.getOrInsertFunction(SanCovWithCheckName, VoidTy, Int32PtrTy, nullptr));
  SanCovTracePCIndir = checkSanitizerInterfaceFunction(
      M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy, nullptr));
  SanCovIndirCallFunction =
      checkSanitizerInterfaceFunction(M.getOrInsertFunction(
          SanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr));
  SanCovTraceCmpFunction[0] =
      checkSanitizerInterfaceFunction(M.getOrInsertFunction(
          SanCovTraceCmp1, VoidTy, IRB.getInt8Ty(), IRB.getInt8Ty(), nullptr));
  SanCovTraceCmpFunction[1] = checkSanitizerInterfaceFunction(
      M.getOrInsertFunction(SanCovTraceCmp2, VoidTy, IRB.getInt16Ty(),
                            IRB.getInt16Ty(), nullptr));
  SanCovTraceCmpFunction[2] = checkSanitizerInterfaceFunction(
      M.getOrInsertFunction(SanCovTraceCmp4, VoidTy, IRB.getInt32Ty(),
                            IRB.getInt32Ty(), nullptr));
  SanCovTraceCmpFunction[3] =
      checkSanitizerInterfaceFunction(M.getOrInsertFunction(
          SanCovTraceCmp8, VoidTy, Int64Ty, Int64Ty, nullptr));

  SanCovTraceDivFunction[0] =
      checkSanitizerInterfaceFunction(M.getOrInsertFunction(
          SanCovTraceDiv4, VoidTy, IRB.getInt32Ty(), nullptr));
  SanCovTraceDivFunction[1] =
      checkSanitizerInterfaceFunction(M.getOrInsertFunction(
          SanCovTraceDiv8, VoidTy, Int64Ty, nullptr));
  SanCovTraceGepFunction =
      checkSanitizerInterfaceFunction(M.getOrInsertFunction(
          SanCovTraceGep, VoidTy, IntptrTy, nullptr));
  SanCovTraceSwitchFunction =
      checkSanitizerInterfaceFunction(M.getOrInsertFunction(
          SanCovTraceSwitchName, VoidTy, Int64Ty, Int64PtrTy, nullptr));

  // We insert an empty inline asm after cov callbacks to avoid callback merge.
  EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
                            StringRef(""), StringRef(""),
                            /*hasSideEffects=*/true);

  SanCovTracePC = checkSanitizerInterfaceFunction(
      M.getOrInsertFunction(SanCovTracePCName, VoidTy, nullptr));
  SanCovTracePCGuard = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
      SanCovTracePCGuardName, VoidTy, Int32PtrTy, nullptr));
  SanCovTraceEnter = checkSanitizerInterfaceFunction(
      M.getOrInsertFunction(SanCovTraceEnterName, VoidTy, Int32PtrTy, nullptr));
  SanCovTraceBB = checkSanitizerInterfaceFunction(
      M.getOrInsertFunction(SanCovTraceBBName, VoidTy, Int32PtrTy, nullptr));

  // At this point we create a dummy array of guards because we don't
  // know how many elements we will need.
  Type *Int32Ty = IRB.getInt32Ty();
  Type *Int8Ty = IRB.getInt8Ty();

  if (!Options.TracePCGuard)
    GuardArray =
        new GlobalVariable(M, Int32Ty, false, GlobalValue::ExternalLinkage,
                           nullptr, "__sancov_gen_cov_tmp");
  if (Options.Use8bitCounters)
    EightBitCounterArray =
        new GlobalVariable(M, Int8Ty, false, GlobalVariable::ExternalLinkage,
                           nullptr, "__sancov_gen_cov_tmp");

  for (auto &F : M)
    runOnFunction(F);

  auto N = NumberOfInstrumentedBlocks();

  GlobalVariable *RealGuardArray = nullptr;
  if (!Options.TracePCGuard) {
    // Now we know how many elements we need. Create an array of guards
    // with one extra element at the beginning for the size.
    Type *Int32ArrayNTy = ArrayType::get(Int32Ty, N + 1);
    RealGuardArray = new GlobalVariable(
        M, Int32ArrayNTy, false, GlobalValue::PrivateLinkage,
        Constant::getNullValue(Int32ArrayNTy), "__sancov_gen_cov");

    // Replace the dummy array with the real one.
    GuardArray->replaceAllUsesWith(
        IRB.CreatePointerCast(RealGuardArray, Int32PtrTy));
    GuardArray->eraseFromParent();
  }

  GlobalVariable *RealEightBitCounterArray;
  if (Options.Use8bitCounters) {
    // Make sure the array is 16-aligned.
    static const int CounterAlignment = 16;
    Type *Int8ArrayNTy = ArrayType::get(Int8Ty, alignTo(N, CounterAlignment));
    RealEightBitCounterArray = new GlobalVariable(
        M, Int8ArrayNTy, false, GlobalValue::PrivateLinkage,
        Constant::getNullValue(Int8ArrayNTy), "__sancov_gen_cov_counter");
    RealEightBitCounterArray->setAlignment(CounterAlignment);
    EightBitCounterArray->replaceAllUsesWith(
        IRB.CreatePointerCast(RealEightBitCounterArray, Int8PtrTy));
    EightBitCounterArray->eraseFromParent();
  }

  // Create variable for module (compilation unit) name
  Constant *ModNameStrConst =
      ConstantDataArray::getString(M.getContext(), M.getName(), true);
  GlobalVariable *ModuleName = new GlobalVariable(
      M, ModNameStrConst->getType(), true, GlobalValue::PrivateLinkage,
      ModNameStrConst, "__sancov_gen_modname");
  if (Options.TracePCGuard) {
    if (HasSancovGuardsSection) {
      Function *CtorFunc;
      GlobalVariable *SecStart = new GlobalVariable(
          M, Int32PtrTy, false, GlobalVariable::ExternalLinkage, nullptr,
          getSanCovTracePCGuardSectionStart());
      SecStart->setVisibility(GlobalValue::HiddenVisibility);
      GlobalVariable *SecEnd = new GlobalVariable(
          M, Int32PtrTy, false, GlobalVariable::ExternalLinkage, nullptr,
          getSanCovTracePCGuardSectionEnd());
      SecEnd->setVisibility(GlobalValue::HiddenVisibility);

      std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
          M, SanCovModuleCtorName, SanCovTracePCGuardInitName,
          {Int32PtrTy, Int32PtrTy},
          {IRB.CreatePointerCast(SecStart, Int32PtrTy),
            IRB.CreatePointerCast(SecEnd, Int32PtrTy)});

      if (TargetTriple.supportsCOMDAT()) {
        // Use comdat to dedup CtorFunc.
        CtorFunc->setComdat(M.getOrInsertComdat(SanCovModuleCtorName));
        appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority, CtorFunc);
      } else {
        appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority);
      }
    }
  } else if (!Options.TracePC) {
    Function *CtorFunc;
    std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
        M, SanCovModuleCtorName, SanCovModuleInitName,
        {Int32PtrTy, IntptrTy, Int8PtrTy, Int8PtrTy},
        {IRB.CreatePointerCast(RealGuardArray, Int32PtrTy),
         ConstantInt::get(IntptrTy, N),
         Options.Use8bitCounters
             ? IRB.CreatePointerCast(RealEightBitCounterArray, Int8PtrTy)
             : Constant::getNullValue(Int8PtrTy),
         IRB.CreatePointerCast(ModuleName, Int8PtrTy)});

    appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority);
  }

  return true;
}
Пример #12
0
/// Evaluate all instructions in block BB, returning true if successful, false
/// if we can't evaluate it.  NewBB returns the next BB that control flows into,
/// or null upon return.
bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst,
                              BasicBlock *&NextBB) {
  // This is the main evaluation loop.
  while (1) {
    Constant *InstResult = nullptr;

    DEBUG(dbgs() << "Evaluating Instruction: " << *CurInst << "\n");

    if (StoreInst *SI = dyn_cast<StoreInst>(CurInst)) {
      if (!SI->isSimple()) {
        DEBUG(dbgs() << "Store is not simple! Can not evaluate.\n");
        return false;  // no volatile/atomic accesses.
      }
      Constant *Ptr = getVal(SI->getOperand(1));
      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr)) {
        DEBUG(dbgs() << "Folding constant ptr expression: " << *Ptr);
        Ptr = ConstantFoldConstantExpression(CE, DL, TLI);
        DEBUG(dbgs() << "; To: " << *Ptr << "\n");
      }
      if (!isSimpleEnoughPointerToCommit(Ptr)) {
        // If this is too complex for us to commit, reject it.
        DEBUG(dbgs() << "Pointer is too complex for us to evaluate store.");
        return false;
      }

      Constant *Val = getVal(SI->getOperand(0));

      // If this might be too difficult for the backend to handle (e.g. the addr
      // of one global variable divided by another) then we can't commit it.
      if (!isSimpleEnoughValueToCommit(Val, SimpleConstants, DL)) {
        DEBUG(dbgs() << "Store value is too complex to evaluate store. " << *Val
              << "\n");
        return false;
      }

      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr)) {
        if (CE->getOpcode() == Instruction::BitCast) {
          DEBUG(dbgs() << "Attempting to resolve bitcast on constant ptr.\n");
          // If we're evaluating a store through a bitcast, then we need
          // to pull the bitcast off the pointer type and push it onto the
          // stored value.
          Ptr = CE->getOperand(0);

          Type *NewTy = cast<PointerType>(Ptr->getType())->getElementType();

          // In order to push the bitcast onto the stored value, a bitcast
          // from NewTy to Val's type must be legal.  If it's not, we can try
          // introspecting NewTy to find a legal conversion.
          while (!Val->getType()->canLosslesslyBitCastTo(NewTy)) {
            // If NewTy is a struct, we can convert the pointer to the struct
            // into a pointer to its first member.
            // FIXME: This could be extended to support arrays as well.
            if (StructType *STy = dyn_cast<StructType>(NewTy)) {
              NewTy = STy->getTypeAtIndex(0U);

              IntegerType *IdxTy = IntegerType::get(NewTy->getContext(), 32);
              Constant *IdxZero = ConstantInt::get(IdxTy, 0, false);
              Constant * const IdxList[] = {IdxZero, IdxZero};

              Ptr = ConstantExpr::getGetElementPtr(nullptr, Ptr, IdxList);
              if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr))
                Ptr = ConstantFoldConstantExpression(CE, DL, TLI);

            // If we can't improve the situation by introspecting NewTy,
            // we have to give up.
            } else {
              DEBUG(dbgs() << "Failed to bitcast constant ptr, can not "
                    "evaluate.\n");
              return false;
            }
          }

          // If we found compatible types, go ahead and push the bitcast
          // onto the stored value.
          Val = ConstantExpr::getBitCast(Val, NewTy);

          DEBUG(dbgs() << "Evaluated bitcast: " << *Val << "\n");
        }
      }

      MutatedMemory[Ptr] = Val;
    } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CurInst)) {
      InstResult = ConstantExpr::get(BO->getOpcode(),
                                     getVal(BO->getOperand(0)),
                                     getVal(BO->getOperand(1)));
      DEBUG(dbgs() << "Found a BinaryOperator! Simplifying: " << *InstResult
            << "\n");
    } else if (CmpInst *CI = dyn_cast<CmpInst>(CurInst)) {
      InstResult = ConstantExpr::getCompare(CI->getPredicate(),
                                            getVal(CI->getOperand(0)),
                                            getVal(CI->getOperand(1)));
      DEBUG(dbgs() << "Found a CmpInst! Simplifying: " << *InstResult
            << "\n");
    } else if (CastInst *CI = dyn_cast<CastInst>(CurInst)) {
      InstResult = ConstantExpr::getCast(CI->getOpcode(),
                                         getVal(CI->getOperand(0)),
                                         CI->getType());
      DEBUG(dbgs() << "Found a Cast! Simplifying: " << *InstResult
            << "\n");
    } else if (SelectInst *SI = dyn_cast<SelectInst>(CurInst)) {
      InstResult = ConstantExpr::getSelect(getVal(SI->getOperand(0)),
                                           getVal(SI->getOperand(1)),
                                           getVal(SI->getOperand(2)));
      DEBUG(dbgs() << "Found a Select! Simplifying: " << *InstResult
            << "\n");
    } else if (auto *EVI = dyn_cast<ExtractValueInst>(CurInst)) {
      InstResult = ConstantExpr::getExtractValue(
          getVal(EVI->getAggregateOperand()), EVI->getIndices());
      DEBUG(dbgs() << "Found an ExtractValueInst! Simplifying: " << *InstResult
                   << "\n");
    } else if (auto *IVI = dyn_cast<InsertValueInst>(CurInst)) {
      InstResult = ConstantExpr::getInsertValue(
          getVal(IVI->getAggregateOperand()),
          getVal(IVI->getInsertedValueOperand()), IVI->getIndices());
      DEBUG(dbgs() << "Found an InsertValueInst! Simplifying: " << *InstResult
                   << "\n");
    } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(CurInst)) {
      Constant *P = getVal(GEP->getOperand(0));
      SmallVector<Constant*, 8> GEPOps;
      for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end();
           i != e; ++i)
        GEPOps.push_back(getVal(*i));
      InstResult =
          ConstantExpr::getGetElementPtr(GEP->getSourceElementType(), P, GEPOps,
                                         cast<GEPOperator>(GEP)->isInBounds());
      DEBUG(dbgs() << "Found a GEP! Simplifying: " << *InstResult
            << "\n");
    } else if (LoadInst *LI = dyn_cast<LoadInst>(CurInst)) {

      if (!LI->isSimple()) {
        DEBUG(dbgs() << "Found a Load! Not a simple load, can not evaluate.\n");
        return false;  // no volatile/atomic accesses.
      }

      Constant *Ptr = getVal(LI->getOperand(0));
      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr)) {
        Ptr = ConstantFoldConstantExpression(CE, DL, TLI);
        DEBUG(dbgs() << "Found a constant pointer expression, constant "
              "folding: " << *Ptr << "\n");
      }
      InstResult = ComputeLoadResult(Ptr);
      if (!InstResult) {
        DEBUG(dbgs() << "Failed to compute load result. Can not evaluate load."
              "\n");
        return false; // Could not evaluate load.
      }

      DEBUG(dbgs() << "Evaluated load: " << *InstResult << "\n");
    } else if (AllocaInst *AI = dyn_cast<AllocaInst>(CurInst)) {
      if (AI->isArrayAllocation()) {
        DEBUG(dbgs() << "Found an array alloca. Can not evaluate.\n");
        return false;  // Cannot handle array allocs.
      }
      Type *Ty = AI->getAllocatedType();
      AllocaTmps.push_back(
          make_unique<GlobalVariable>(Ty, false, GlobalValue::InternalLinkage,
                                      UndefValue::get(Ty), AI->getName()));
      InstResult = AllocaTmps.back().get();
      DEBUG(dbgs() << "Found an alloca. Result: " << *InstResult << "\n");
    } else if (isa<CallInst>(CurInst) || isa<InvokeInst>(CurInst)) {
      CallSite CS(&*CurInst);

      // Debug info can safely be ignored here.
      if (isa<DbgInfoIntrinsic>(CS.getInstruction())) {
        DEBUG(dbgs() << "Ignoring debug info.\n");
        ++CurInst;
        continue;
      }

      // Cannot handle inline asm.
      if (isa<InlineAsm>(CS.getCalledValue())) {
        DEBUG(dbgs() << "Found inline asm, can not evaluate.\n");
        return false;
      }

      if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) {
        if (MemSetInst *MSI = dyn_cast<MemSetInst>(II)) {
          if (MSI->isVolatile()) {
            DEBUG(dbgs() << "Can not optimize a volatile memset " <<
                  "intrinsic.\n");
            return false;
          }
          Constant *Ptr = getVal(MSI->getDest());
          Constant *Val = getVal(MSI->getValue());
          Constant *DestVal = ComputeLoadResult(getVal(Ptr));
          if (Val->isNullValue() && DestVal && DestVal->isNullValue()) {
            // This memset is a no-op.
            DEBUG(dbgs() << "Ignoring no-op memset.\n");
            ++CurInst;
            continue;
          }
        }

        if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
            II->getIntrinsicID() == Intrinsic::lifetime_end) {
          DEBUG(dbgs() << "Ignoring lifetime intrinsic.\n");
          ++CurInst;
          continue;
        }

        if (II->getIntrinsicID() == Intrinsic::invariant_start) {
          // We don't insert an entry into Values, as it doesn't have a
          // meaningful return value.
          if (!II->use_empty()) {
            DEBUG(dbgs() << "Found unused invariant_start. Can't evaluate.\n");
            return false;
          }
          ConstantInt *Size = cast<ConstantInt>(II->getArgOperand(0));
          Value *PtrArg = getVal(II->getArgOperand(1));
          Value *Ptr = PtrArg->stripPointerCasts();
          if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Ptr)) {
            Type *ElemTy = GV->getValueType();
            if (!Size->isAllOnesValue() &&
                Size->getValue().getLimitedValue() >=
                    DL.getTypeStoreSize(ElemTy)) {
              Invariants.insert(GV);
              DEBUG(dbgs() << "Found a global var that is an invariant: " << *GV
                    << "\n");
            } else {
              DEBUG(dbgs() << "Found a global var, but can not treat it as an "
                    "invariant.\n");
            }
          }
          // Continue even if we do nothing.
          ++CurInst;
          continue;
        } else if (II->getIntrinsicID() == Intrinsic::assume) {
          DEBUG(dbgs() << "Skipping assume intrinsic.\n");
          ++CurInst;
          continue;
        }

        DEBUG(dbgs() << "Unknown intrinsic. Can not evaluate.\n");
        return false;
      }

      // Resolve function pointers.
      Function *Callee = dyn_cast<Function>(getVal(CS.getCalledValue()));
      if (!Callee || Callee->mayBeOverridden()) {
        DEBUG(dbgs() << "Can not resolve function pointer.\n");
        return false;  // Cannot resolve.
      }

      SmallVector<Constant*, 8> Formals;
      for (User::op_iterator i = CS.arg_begin(), e = CS.arg_end(); i != e; ++i)
        Formals.push_back(getVal(*i));

      if (Callee->isDeclaration()) {
        // If this is a function we can constant fold, do it.
        if (Constant *C = ConstantFoldCall(Callee, Formals, TLI)) {
          InstResult = C;
          DEBUG(dbgs() << "Constant folded function call. Result: " <<
                *InstResult << "\n");
        } else {
          DEBUG(dbgs() << "Can not constant fold function call.\n");
          return false;
        }
      } else {
        if (Callee->getFunctionType()->isVarArg()) {
          DEBUG(dbgs() << "Can not constant fold vararg function call.\n");
          return false;
        }

        Constant *RetVal = nullptr;
        // Execute the call, if successful, use the return value.
        ValueStack.emplace_back();
        if (!EvaluateFunction(Callee, RetVal, Formals)) {
          DEBUG(dbgs() << "Failed to evaluate function.\n");
          return false;
        }
        ValueStack.pop_back();
        InstResult = RetVal;

        if (InstResult) {
          DEBUG(dbgs() << "Successfully evaluated function. Result: "
                       << *InstResult << "\n\n");
        } else {
          DEBUG(dbgs() << "Successfully evaluated function. Result: 0\n\n");
        }
      }
    } else if (isa<TerminatorInst>(CurInst)) {
      DEBUG(dbgs() << "Found a terminator instruction.\n");

      if (BranchInst *BI = dyn_cast<BranchInst>(CurInst)) {
        if (BI->isUnconditional()) {
          NextBB = BI->getSuccessor(0);
        } else {
          ConstantInt *Cond =
            dyn_cast<ConstantInt>(getVal(BI->getCondition()));
          if (!Cond) return false;  // Cannot determine.

          NextBB = BI->getSuccessor(!Cond->getZExtValue());
        }
      } else if (SwitchInst *SI = dyn_cast<SwitchInst>(CurInst)) {
        ConstantInt *Val =
          dyn_cast<ConstantInt>(getVal(SI->getCondition()));
        if (!Val) return false;  // Cannot determine.
        NextBB = SI->findCaseValue(Val).getCaseSuccessor();
      } else if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(CurInst)) {
        Value *Val = getVal(IBI->getAddress())->stripPointerCasts();
        if (BlockAddress *BA = dyn_cast<BlockAddress>(Val))
          NextBB = BA->getBasicBlock();
        else
          return false;  // Cannot determine.
      } else if (isa<ReturnInst>(CurInst)) {
        NextBB = nullptr;
      } else {
        // invoke, unwind, resume, unreachable.
        DEBUG(dbgs() << "Can not handle terminator.");
        return false;  // Cannot handle this terminator.
      }

      // We succeeded at evaluating this block!
      DEBUG(dbgs() << "Successfully evaluated block.\n");
      return true;
    } else {
      // Did not know how to evaluate this!
      DEBUG(dbgs() << "Failed to evaluate block due to unhandled instruction."
            "\n");
      return false;
    }

    if (!CurInst->use_empty()) {
      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(InstResult))
        InstResult = ConstantFoldConstantExpression(CE, DL, TLI);

      setVal(&*CurInst, InstResult);
    }

    // If we just processed an invoke, we finished evaluating the block.
    if (InvokeInst *II = dyn_cast<InvokeInst>(CurInst)) {
      NextBB = II->getNormalDest();
      DEBUG(dbgs() << "Found an invoke instruction. Finished Block.\n\n");
      return true;
    }

    // Advance program counter.
    ++CurInst;
  }
}
Пример #13
0
void InitializeSoftBound:: constructCheckHandlers(Module & module){

  Type* void_ty = Type::getVoidTy(module.getContext());

  Type* void_ptr_ty = PointerType::getUnqual(Type::getInt8Ty(module.getContext()));
  Type* size_ty = Type::getInt64Ty(module.getContext());

  module.getOrInsertFunction("__softboundcets_spatial_load_dereference_check",
                             void_ty, void_ptr_ty, void_ptr_ty, 
                             void_ptr_ty, size_ty, NULL);

  module.getOrInsertFunction("__softboundcets_spatial_store_dereference_check", 
                             void_ty, void_ptr_ty, void_ptr_ty, 
                             void_ptr_ty, size_ty, NULL);

  module.getOrInsertFunction("__softboundcets_temporal_load_dereference_check", 
                             void_ty, void_ptr_ty, size_ty, 
                             void_ptr_ty, void_ptr_ty, NULL);

  module.getOrInsertFunction("__softboundcets_temporal_store_dereference_check", 
                             void_ty, void_ptr_ty, size_ty, 
                             void_ptr_ty, void_ptr_ty, NULL);


  Function* global_init = (Function *) module.getOrInsertFunction("__softboundcets_global_init", 
                                                                  void_ty, NULL);

  global_init->setDoesNotThrow();
  global_init->setLinkage(GlobalValue::InternalLinkage);

  BasicBlock* BB = BasicBlock::Create(module.getContext(), 
                                      "entry", global_init);
  
  Function* softboundcets_init = (Function*) module.getOrInsertFunction("__softboundcets_init", void_ty, Type::getInt32Ty(module.getContext()), NULL);

  
  SmallVector<Value*, 8> args;
  Constant * const_one = ConstantInt::get(Type::getInt32Ty(module.getContext()), 1);
  
  args.push_back(const_one);
  Instruction* ret = ReturnInst::Create(module.getContext(), BB);
  
  CallInst::Create(softboundcets_init, args, "", ret);



  Type * Int32Type = IntegerType::getInt32Ty(module.getContext());
  std::vector<Constant *> CtorInits;
  CtorInits.push_back(ConstantInt::get(Int32Type, 0));
  CtorInits.push_back(global_init);
  StructType * ST = ConstantStruct::getTypeForElements(CtorInits, false);
  Constant * RuntimeCtorInit = ConstantStruct::get(ST, CtorInits);

  //
  // Get the current set of static global constructors and add the new ctor
  // to the list.
  //
  std::vector<Constant *> CurrentCtors;
  GlobalVariable * GVCtor = module.getNamedGlobal ("llvm.global_ctors");
  if (GVCtor) {
    if (Constant * C = GVCtor->getInitializer()) {
      for (unsigned index = 0; index < C->getNumOperands(); ++index) {
        CurrentCtors.push_back (dyn_cast<Constant>(C->getOperand (index)));
      }
    }
  }
  CurrentCtors.push_back(RuntimeCtorInit);

  //
  // Create a new initializer.
  //
  ArrayType * AT = ArrayType::get (RuntimeCtorInit-> getType(),
                                   CurrentCtors.size());
  Constant * NewInit = ConstantArray::get (AT, CurrentCtors);

  //
  // Create the new llvm.global_ctors global variable and remove the old one
  // if it existed.
  //
  Value * newGVCtor = new GlobalVariable (module,
                                          NewInit->getType(),
                                          false,
                                          GlobalValue::AppendingLinkage,
                                          NewInit,
                                          "llvm.global_ctors");
  if (GVCtor) {
    newGVCtor->takeName (GVCtor);
    GVCtor->eraseFromParent ();
  }



}
Пример #14
0
	virtual bool runOnModule(Module &M) {

		LLVMContext &C = M.getContext();
		Function *printError_func = (Function*)M.getOrInsertFunction("printErrorMessage", Type::getVoidTy(C), NULL);

		BasicBlock* entryBlock = BasicBlock::Create(C, "", printError_func);
		IRBuilder<> builder(entryBlock);

		Constant *msg = ConstantArray::get(C, "ERROR!  Array Index Out of Bounds", true);

		Constant *zero_32 = Constant::getNullValue(IntegerType::getInt32Ty(C));
		Constant *gep_params[] = {zero_32, zero_32};


		GlobalVariable *errorMsg = new GlobalVariable(M, msg->getType(), true, GlobalValue::InternalLinkage, msg, "errorMsg");
		Function *puts_func = (Function*)(M.getOrInsertFunction("puts", IntegerType::getInt32Ty(C), PointerType::getUnqual(IntegerType::getInt8Ty(C)), NULL));
		Constant *msgptr = ConstantExpr::getGetElementPtr(errorMsg, gep_params);

		Value *puts_params[] = {msgptr};

		CallInst *puts_call = builder.CreateCall(puts_func, puts_params);
		puts_call->setTailCall(false);

		Function *exit_func = cast<Function>(M.getOrInsertFunction("exit", IntegerType::getVoidTy(C), Type::getInt32Ty(C),NULL));

		Value *exit_val = ConstantInt::get(IntegerType::getInt32Ty(C), 1);
		
		//create exit block.  This block prints the error and calls exit system function
		BasicBlock* exitBlock = BasicBlock::Create(C, "exitBlock", printError_func);
		builder.CreateBr(exitBlock);
		builder.SetInsertPoint(exitBlock);


		builder.CreateCall(exit_func,exit_val);
		builder.CreateBr(exitBlock);

		int checksInserted = 0;

		for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
		{
			//leave func defs alone
			if (!MI->isDeclaration()) 
			{
				for (inst_iterator I = inst_begin(*MI), E = inst_end(*MI); I != E; ++I)
				{
					Instruction *inst = &*I;
					
					if(GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>(inst))
					{
						if (const ArrayType *ar = dyn_cast<ArrayType>(gep->getPointerOperandType()->getElementType()))
						{           
							//increment checks inserted counter
							checksInserted++;
	
							//create split in basic block for function call insertion (branch)
							Instruction* next = inst->getNextNode();
							BasicBlock* oldBlock = inst->getParent();
							BasicBlock* newBlock = SplitBlock(oldBlock, next, this);

							//get upper limit and index used
							unsigned upperLim = ar->getNumElements();
							int index = gep->getNumOperands() - 1;
							Value *vIndexUsed = gep->getOperand(index);
							Value *vUpperLimit = ConstantInt::get(vIndexUsed->getType(), upperLim);

							BasicBlock* checkUpperBlock = BasicBlock::Create(C, "checkUpperBlock", MI, newBlock);
							BasicBlock* checkLowerBlock = BasicBlock::Create(C, "checkLowerBlock", MI, checkUpperBlock);
							
							builder.SetInsertPoint(oldBlock);
							
							//remove old terminator
							TerminatorInst* term = oldBlock->getTerminator();
							term->eraseFromParent();
							//insert new one
							builder.CreateBr(checkUpperBlock);
							
							//configure uppper bound test
							builder.SetInsertPoint(checkUpperBlock);
							Value* condUpperInst = builder.CreateICmpSLT(vIndexUsed, vUpperLimit, "checkUpperBounds");
							BasicBlock* errorBlock = BasicBlock::Create(C, "errorBlock", MI, newBlock);
							builder.CreateCondBr(condUpperInst, checkLowerBlock, errorBlock);

							//configure lower bound test
							builder.SetInsertPoint(checkLowerBlock);
							Value *vLowerLimit = ConstantInt::get(vIndexUsed->getType(), -1);
							Value *condLowerInst = builder.CreateICmpSGT(vIndexUsed, vLowerLimit, "checkLowerBounds");
							builder.CreateCondBr(condLowerInst, newBlock, errorBlock);

							//setup error block.  All this block does is call func to print error and exit
							builder.SetInsertPoint(errorBlock);
							builder.CreateCall(printError_func);
							builder.CreateBr(errorBlock);
						}
					}				
				}
			}
		}
		errs() << "This pass has inserted " << checksInserted << " checks\n";
      return true;
	}
Пример #15
0
Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags,
                      ValueMapTypeRemapper *TypeMapper) {
  ValueToValueMapTy::iterator I = VM.find(V);
  
  // If the value already exists in the map, use it.
  if (I != VM.end() && I->second) return I->second;
  
  // Global values do not need to be seeded into the VM if they
  // are using the identity mapping.
  if (isa<GlobalValue>(V) || isa<MDString>(V))
    return VM[V] = const_cast<Value*>(V);
  
  if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
    // Inline asm may need *type* remapping.
    FunctionType *NewTy = IA->getFunctionType();
    if (TypeMapper) {
      NewTy = cast<FunctionType>(TypeMapper->remapType(NewTy));

      if (NewTy != IA->getFunctionType())
        V = InlineAsm::get(NewTy, IA->getAsmString(), IA->getConstraintString(),
                           IA->hasSideEffects(), IA->isAlignStack());
    }
    
    return VM[V] = const_cast<Value*>(V);
  }
  

  if (const MDNode *MD = dyn_cast<MDNode>(V)) {
    // If this is a module-level metadata and we know that nothing at the module
    // level is changing, then use an identity mapping.
    if (!MD->isFunctionLocal() && (Flags & RF_NoModuleLevelChanges))
      return VM[V] = const_cast<Value*>(V);
    
    // Create a dummy node in case we have a metadata cycle.
    MDNode *Dummy = MDNode::getTemporary(V->getContext(), ArrayRef<Value*>());
    VM[V] = Dummy;
    
    // Check all operands to see if any need to be remapped.
    for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) {
      Value *OP = MD->getOperand(i);
      if (OP == 0 || MapValue(OP, VM, Flags, TypeMapper) == OP) continue;

      // Ok, at least one operand needs remapping.  
      SmallVector<Value*, 4> Elts;
      Elts.reserve(MD->getNumOperands());
      for (i = 0; i != e; ++i) {
        Value *Op = MD->getOperand(i);
        Elts.push_back(Op ? MapValue(Op, VM, Flags, TypeMapper) : 0);
      }
      MDNode *NewMD = MDNode::get(V->getContext(), Elts);
      Dummy->replaceAllUsesWith(NewMD);
      VM[V] = NewMD;
      MDNode::deleteTemporary(Dummy);
      return NewMD;
    }

    VM[V] = const_cast<Value*>(V);
    MDNode::deleteTemporary(Dummy);

    // No operands needed remapping.  Use an identity mapping.
    return const_cast<Value*>(V);
  }

  // Okay, this either must be a constant (which may or may not be mappable) or
  // is something that is not in the mapping table.
  Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));
  if (C == 0)
    return 0;
  
  if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
    Function *F = 
      cast<Function>(MapValue(BA->getFunction(), VM, Flags, TypeMapper));
    BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(), VM,
                                                       Flags, TypeMapper));
    return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock());
  }
  
  // Otherwise, we have some other constant to remap.  Start by checking to see
  // if all operands have an identity remapping.
  unsigned OpNo = 0, NumOperands = C->getNumOperands();
  Value *Mapped = 0;
  for (; OpNo != NumOperands; ++OpNo) {
    Value *Op = C->getOperand(OpNo);
    Mapped = MapValue(Op, VM, Flags, TypeMapper);
    if (Mapped != C) break;
  }
  
  // See if the type mapper wants to remap the type as well.
  Type *NewTy = C->getType();
  if (TypeMapper)
    NewTy = TypeMapper->remapType(NewTy);

  // If the result type and all operands match up, then just insert an identity
  // mapping.
  if (OpNo == NumOperands && NewTy == C->getType())
    return VM[V] = C;
  
  // Okay, we need to create a new constant.  We've already processed some or
  // all of the operands, set them all up now.
  SmallVector<Constant*, 8> Ops;
  Ops.reserve(NumOperands);
  for (unsigned j = 0; j != OpNo; ++j)
    Ops.push_back(cast<Constant>(C->getOperand(j)));
  
  // If one of the operands mismatch, push it and the other mapped operands.
  if (OpNo != NumOperands) {
    Ops.push_back(cast<Constant>(Mapped));
  
    // Map the rest of the operands that aren't processed yet.
    for (++OpNo; OpNo != NumOperands; ++OpNo)
      Ops.push_back(MapValue(cast<Constant>(C->getOperand(OpNo)), VM,
                             Flags, TypeMapper));
  }
  
  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
    return VM[V] = CE->getWithOperands(Ops, NewTy);
  if (isa<ConstantArray>(C))
    return VM[V] = ConstantArray::get(cast<ArrayType>(NewTy), Ops);
  if (isa<ConstantStruct>(C))
    return VM[V] = ConstantStruct::get(cast<StructType>(NewTy), Ops);
  if (isa<ConstantVector>(C))
    return VM[V] = ConstantVector::get(Ops);
  // If this is a no-operand constant, it must be because the type was remapped.
  if (isa<UndefValue>(C))
    return VM[V] = UndefValue::get(NewTy);
  if (isa<ConstantAggregateZero>(C))
    return VM[V] = ConstantAggregateZero::get(NewTy);
  assert(isa<ConstantPointerNull>(C));
  return VM[V] = ConstantPointerNull::get(cast<PointerType>(NewTy));
}
Пример #16
0
// ResolveConstantExpr - Resolve the constant expression until it stop
// yielding other constant expressions.
CstExprResTy ELFWriter::ResolveConstantExpr(const Constant *CV) {
  const TargetData *TD = TM.getTargetData();
  
  // There ins't constant expression inside others anymore
  if (!isa<ConstantExpr>(CV))
    return std::make_pair(CV, 0);

  const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV);
  switch (CE->getOpcode()) {
  case Instruction::BitCast:
    return ResolveConstantExpr(CE->getOperand(0));
  
  case Instruction::GetElementPtr: {
    const Constant *ptrVal = CE->getOperand(0);
    SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end());
    int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0],
                                          idxVec.size());
    return std::make_pair(ptrVal, Offset);
  }
  case Instruction::IntToPtr: {
    Constant *Op = CE->getOperand(0);
    Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(CV->getContext()),
                                      false/*ZExt*/);
    return ResolveConstantExpr(Op);
  }
  case Instruction::PtrToInt: {
    Constant *Op = CE->getOperand(0);
    const Type *Ty = CE->getType();

    // We can emit the pointer value into this slot if the slot is an
    // integer slot greater or equal to the size of the pointer.
    if (TD->getTypeAllocSize(Ty) == TD->getTypeAllocSize(Op->getType()))
      return ResolveConstantExpr(Op);

    llvm_unreachable("Integer size less then pointer size");
  }
  case Instruction::Add:
  case Instruction::Sub: {
    // Only handle cases where there's a constant expression with GlobalValue
    // as first operand and ConstantInt as second, which are the cases we can
    // solve direclty using a relocation entry. GlobalValue=Op0, CstInt=Op1
    // 1)  Instruction::Add  => (global) + CstInt
    // 2)  Instruction::Sub  => (global) + -CstInt
    const Constant *Op0 = CE->getOperand(0); 
    const Constant *Op1 = CE->getOperand(1); 
    assert(isa<ConstantInt>(Op1) && "Op1 must be a ConstantInt");

    CstExprResTy Res = ResolveConstantExpr(Op0);
    assert(isa<GlobalValue>(Res.first) && "Op0 must be a GlobalValue");

    const APInt &RHS = cast<ConstantInt>(Op1)->getValue();
    switch (CE->getOpcode()) {
    case Instruction::Add: 
      return std::make_pair(Res.first, RHS.getSExtValue());
    case Instruction::Sub:
      return std::make_pair(Res.first, (-RHS).getSExtValue());
    }
  }
  }

  report_fatal_error(CE->getOpcodeName() +
                     StringRef(": Unsupported ConstantExpr type"));

  return std::make_pair(CV, 0); // silence warning
}
Пример #17
0
/// CleanupAndPrepareModules - Get the specified modules ready for code
/// generator testing.
///
static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
                                     Module *Safe) {
  // Clean up the modules, removing extra cruft that we don't need anymore...
  Test = BD.performFinalCleanups(Test);

  // If we are executing the JIT, we have several nasty issues to take care of.
  if (!BD.isExecutingJIT()) return;

  // First, if the main function is in the Safe module, we must add a stub to
  // the Test module to call into it.  Thus, we create a new function `main'
  // which just calls the old one.
  if (Function *oldMain = Safe->getFunction("main"))
    if (!oldMain->isDeclaration()) {
      // Rename it
      oldMain->setName("llvm_bugpoint_old_main");
      // Create a NEW `main' function with same type in the test module.
      Function *newMain = Function::Create(oldMain->getFunctionType(),
                                           GlobalValue::ExternalLinkage,
                                           "main", Test);
      // Create an `oldmain' prototype in the test module, which will
      // corresponds to the real main function in the same module.
      Function *oldMainProto = Function::Create(oldMain->getFunctionType(),
                                                GlobalValue::ExternalLinkage,
                                                oldMain->getName(), Test);
      // Set up and remember the argument list for the main function.
      std::vector<Value*> args;
      for (Function::arg_iterator
             I = newMain->arg_begin(), E = newMain->arg_end(),
             OI = oldMain->arg_begin(); I != E; ++I, ++OI) {
        I->setName(OI->getName());    // Copy argument names from oldMain
        args.push_back(I);
      }

      // Call the old main function and return its result
      BasicBlock *BB = BasicBlock::Create(Safe->getContext(), "entry", newMain);
      CallInst *call = CallInst::Create(oldMainProto, args, "", BB);

      // If the type of old function wasn't void, return value of call
      ReturnInst::Create(Safe->getContext(), call, BB);
    }

  // The second nasty issue we must deal with in the JIT is that the Safe
  // module cannot directly reference any functions defined in the test
  // module.  Instead, we use a JIT API call to dynamically resolve the
  // symbol.

  // Add the resolver to the Safe module.
  // Prototype: void *getPointerToNamedFunction(const char* Name)
  Constant *resolverFunc =
    Safe->getOrInsertFunction("getPointerToNamedFunction",
                    Type::getInt8PtrTy(Safe->getContext()),
                    Type::getInt8PtrTy(Safe->getContext()),
                       (Type *)0);

  // Use the function we just added to get addresses of functions we need.
  for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) {
    if (F->isDeclaration() && !F->use_empty() && &*F != resolverFunc &&
        !F->isIntrinsic() /* ignore intrinsics */) {
      Function *TestFn = Test->getFunction(F->getName());

      // Don't forward functions which are external in the test module too.
      if (TestFn && !TestFn->isDeclaration()) {
        // 1. Add a string constant with its name to the global file
        Constant *InitArray =
          ConstantDataArray::getString(F->getContext(), F->getName());
        GlobalVariable *funcName =
          new GlobalVariable(*Safe, InitArray->getType(), true /*isConstant*/,
                             GlobalValue::InternalLinkage, InitArray,
                             F->getName() + "_name");

        // 2. Use `GetElementPtr *funcName, 0, 0' to convert the string to an
        // sbyte* so it matches the signature of the resolver function.

        // GetElementPtr *funcName, ulong 0, ulong 0
        std::vector<Constant*> GEPargs(2,
                     Constant::getNullValue(Type::getInt32Ty(F->getContext())));
        Value *GEP = ConstantExpr::getGetElementPtr(funcName, GEPargs);
        std::vector<Value*> ResolverArgs;
        ResolverArgs.push_back(GEP);

        // Rewrite uses of F in global initializers, etc. to uses of a wrapper
        // function that dynamically resolves the calls to F via our JIT API
        if (!F->use_empty()) {
          // Create a new global to hold the cached function pointer.
          Constant *NullPtr = ConstantPointerNull::get(F->getType());
          GlobalVariable *Cache =
            new GlobalVariable(*F->getParent(), F->getType(),
                               false, GlobalValue::InternalLinkage,
                               NullPtr,F->getName()+".fpcache");

          // Construct a new stub function that will re-route calls to F
          FunctionType *FuncTy = F->getFunctionType();
          Function *FuncWrapper = Function::Create(FuncTy,
                                                   GlobalValue::InternalLinkage,
                                                   F->getName() + "_wrapper",
                                                   F->getParent());
          BasicBlock *EntryBB  = BasicBlock::Create(F->getContext(),
                                                    "entry", FuncWrapper);
          BasicBlock *DoCallBB = BasicBlock::Create(F->getContext(),
                                                    "usecache", FuncWrapper);
          BasicBlock *LookupBB = BasicBlock::Create(F->getContext(),
                                                    "lookupfp", FuncWrapper);

          // Check to see if we already looked up the value.
          Value *CachedVal = new LoadInst(Cache, "fpcache", EntryBB);
          Value *IsNull = new ICmpInst(*EntryBB, ICmpInst::ICMP_EQ, CachedVal,
                                       NullPtr, "isNull");
          BranchInst::Create(LookupBB, DoCallBB, IsNull, EntryBB);

          // Resolve the call to function F via the JIT API:
          //
          // call resolver(GetElementPtr...)
          CallInst *Resolver =
            CallInst::Create(resolverFunc, ResolverArgs, "resolver", LookupBB);

          // Cast the result from the resolver to correctly-typed function.
          CastInst *CastedResolver =
            new BitCastInst(Resolver,
                            PointerType::getUnqual(F->getFunctionType()),
                            "resolverCast", LookupBB);

          // Save the value in our cache.
          new StoreInst(CastedResolver, Cache, LookupBB);
          BranchInst::Create(DoCallBB, LookupBB);

          PHINode *FuncPtr = PHINode::Create(NullPtr->getType(), 2,
                                             "fp", DoCallBB);
          FuncPtr->addIncoming(CastedResolver, LookupBB);
          FuncPtr->addIncoming(CachedVal, EntryBB);

          // Save the argument list.
          std::vector<Value*> Args;
          for (Function::arg_iterator i = FuncWrapper->arg_begin(),
                 e = FuncWrapper->arg_end(); i != e; ++i)
            Args.push_back(i);

          // Pass on the arguments to the real function, return its result
          if (F->getReturnType()->isVoidTy()) {
            CallInst::Create(FuncPtr, Args, "", DoCallBB);
            ReturnInst::Create(F->getContext(), DoCallBB);
          } else {
            CallInst *Call = CallInst::Create(FuncPtr, Args,
                                              "retval", DoCallBB);
            ReturnInst::Create(F->getContext(),Call, DoCallBB);
          }

          // Use the wrapper function instead of the old function
          F->replaceAllUsesWith(FuncWrapper);
        }
      }
    }
  }

  if (verifyModule(*Test) || verifyModule(*Safe)) {
    errs() << "Bugpoint has a bug, which corrupted a module!!\n";
    abort();
  }
}
Пример #18
0
Instruction *InstCombiner::visitSRem(BinaryOperator &I) {
  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

  if (Value *V = SimplifyVectorOp(I))
    return ReplaceInstUsesWith(I, V);

  if (Value *V = SimplifySRemInst(Op0, Op1, DL))
    return ReplaceInstUsesWith(I, V);

  // Handle the integer rem common cases
  if (Instruction *Common = commonIRemTransforms(I))
    return Common;

  if (Value *RHSNeg = dyn_castNegVal(Op1))
    if (!isa<Constant>(RHSNeg) ||
        (isa<ConstantInt>(RHSNeg) &&
         cast<ConstantInt>(RHSNeg)->getValue().isStrictlyPositive())) {
      // X % -Y -> X % Y
      Worklist.AddValue(I.getOperand(1));
      I.setOperand(1, RHSNeg);
      return &I;
    }

  // If the sign bits of both operands are zero (i.e. we can prove they are
  // unsigned inputs), turn this into a urem.
  if (I.getType()->isIntegerTy()) {
    APInt Mask(APInt::getSignBit(I.getType()->getPrimitiveSizeInBits()));
    if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
      // X srem Y -> X urem Y, iff X and Y don't have sign bit set
      return BinaryOperator::CreateURem(Op0, Op1, I.getName());
    }
  }

  // If it's a constant vector, flip any negative values positive.
  if (isa<ConstantVector>(Op1) || isa<ConstantDataVector>(Op1)) {
    Constant *C = cast<Constant>(Op1);
    unsigned VWidth = C->getType()->getVectorNumElements();

    bool hasNegative = false;
    bool hasMissing = false;
    for (unsigned i = 0; i != VWidth; ++i) {
      Constant *Elt = C->getAggregateElement(i);
      if (!Elt) {
        hasMissing = true;
        break;
      }

      if (ConstantInt *RHS = dyn_cast<ConstantInt>(Elt))
        if (RHS->isNegative())
          hasNegative = true;
    }

    if (hasNegative && !hasMissing) {
      SmallVector<Constant *, 16> Elts(VWidth);
      for (unsigned i = 0; i != VWidth; ++i) {
        Elts[i] = C->getAggregateElement(i);  // Handle undef, etc.
        if (ConstantInt *RHS = dyn_cast<ConstantInt>(Elts[i])) {
          if (RHS->isNegative())
            Elts[i] = cast<ConstantInt>(ConstantExpr::getNeg(RHS));
        }
      }

      Constant *NewRHSV = ConstantVector::get(Elts);
      if (NewRHSV != C) {  // Don't loop on -MININT
        Worklist.AddValue(I.getOperand(1));
        I.setOperand(1, NewRHSV);
        return &I;
      }
    }
  }

  return nullptr;
}
Пример #19
0
Value *Mapper::mapValue(const Value *V) {
  ValueToValueMapTy::iterator I = getVM().find(V);

  // If the value already exists in the map, use it.
  if (I != getVM().end()) {
    assert(I->second && "Unexpected null mapping");
    return I->second;
  }

  // If we have a materializer and it can materialize a value, use that.
  if (auto *Materializer = getMaterializer()) {
    if (Value *NewV = Materializer->materialize(const_cast<Value *>(V))) {
      getVM()[V] = NewV;
      return NewV;
    }
  }

  // Global values do not need to be seeded into the VM if they
  // are using the identity mapping.
  if (isa<GlobalValue>(V)) {
    if (Flags & RF_NullMapMissingGlobalValues)
      return nullptr;
    return getVM()[V] = const_cast<Value *>(V);
  }

  if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
    // Inline asm may need *type* remapping.
    FunctionType *NewTy = IA->getFunctionType();
    if (TypeMapper) {
      NewTy = cast<FunctionType>(TypeMapper->remapType(NewTy));

      if (NewTy != IA->getFunctionType())
        V = InlineAsm::get(NewTy, IA->getAsmString(), IA->getConstraintString(),
                           IA->hasSideEffects(), IA->isAlignStack());
    }

    return getVM()[V] = const_cast<Value *>(V);
  }

  if (const auto *MDV = dyn_cast<MetadataAsValue>(V)) {
    const Metadata *MD = MDV->getMetadata();

    if (auto *LAM = dyn_cast<LocalAsMetadata>(MD)) {
      // Look through to grab the local value.
      if (Value *LV = mapValue(LAM->getValue())) {
        if (V == LAM->getValue())
          return const_cast<Value *>(V);
        return MetadataAsValue::get(V->getContext(), ValueAsMetadata::get(LV));
      }

      // FIXME: always return nullptr once Verifier::verifyDominatesUse()
      // ensures metadata operands only reference defined SSA values.
      return (Flags & RF_IgnoreMissingLocals)
                 ? nullptr
                 : MetadataAsValue::get(V->getContext(),
                                        MDTuple::get(V->getContext(), None));
    }

    // If this is a module-level metadata and we know that nothing at the module
    // level is changing, then use an identity mapping.
    if (Flags & RF_NoModuleLevelChanges)
      return getVM()[V] = const_cast<Value *>(V);

    // Map the metadata and turn it into a value.
    auto *MappedMD = mapMetadata(MD);
    if (MD == MappedMD)
      return getVM()[V] = const_cast<Value *>(V);
    return getVM()[V] = MetadataAsValue::get(V->getContext(), MappedMD);
  }

  // Okay, this either must be a constant (which may or may not be mappable) or
  // is something that is not in the mapping table.
  Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));
  if (!C)
    return nullptr;

  if (BlockAddress *BA = dyn_cast<BlockAddress>(C))
    return mapBlockAddress(*BA);

  auto mapValueOrNull = [this](Value *V) {
    auto Mapped = mapValue(V);
    assert((Mapped || (Flags & RF_NullMapMissingGlobalValues)) &&
           "Unexpected null mapping for constant operand without "
           "NullMapMissingGlobalValues flag");
    return Mapped;
  };

  // Otherwise, we have some other constant to remap.  Start by checking to see
  // if all operands have an identity remapping.
  unsigned OpNo = 0, NumOperands = C->getNumOperands();
  Value *Mapped = nullptr;
  for (; OpNo != NumOperands; ++OpNo) {
    Value *Op = C->getOperand(OpNo);
    Mapped = mapValueOrNull(Op);
    if (!Mapped)
      return nullptr;
    if (Mapped != Op)
      break;
  }

  // See if the type mapper wants to remap the type as well.
  Type *NewTy = C->getType();
  if (TypeMapper)
    NewTy = TypeMapper->remapType(NewTy);

  // If the result type and all operands match up, then just insert an identity
  // mapping.
  if (OpNo == NumOperands && NewTy == C->getType())
    return getVM()[V] = C;

  // Okay, we need to create a new constant.  We've already processed some or
  // all of the operands, set them all up now.
  SmallVector<Constant*, 8> Ops;
  Ops.reserve(NumOperands);
  for (unsigned j = 0; j != OpNo; ++j)
    Ops.push_back(cast<Constant>(C->getOperand(j)));

  // If one of the operands mismatch, push it and the other mapped operands.
  if (OpNo != NumOperands) {
    Ops.push_back(cast<Constant>(Mapped));

    // Map the rest of the operands that aren't processed yet.
    for (++OpNo; OpNo != NumOperands; ++OpNo) {
      Mapped = mapValueOrNull(C->getOperand(OpNo));
      if (!Mapped)
        return nullptr;
      Ops.push_back(cast<Constant>(Mapped));
    }
  }
  Type *NewSrcTy = nullptr;
  if (TypeMapper)
    if (auto *GEPO = dyn_cast<GEPOperator>(C))
      NewSrcTy = TypeMapper->remapType(GEPO->getSourceElementType());

  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
    return getVM()[V] = CE->getWithOperands(Ops, NewTy, false, NewSrcTy);
  if (isa<ConstantArray>(C))
    return getVM()[V] = ConstantArray::get(cast<ArrayType>(NewTy), Ops);
  if (isa<ConstantStruct>(C))
    return getVM()[V] = ConstantStruct::get(cast<StructType>(NewTy), Ops);
  if (isa<ConstantVector>(C))
    return getVM()[V] = ConstantVector::get(Ops);
  // If this is a no-operand constant, it must be because the type was remapped.
  if (isa<UndefValue>(C))
    return getVM()[V] = UndefValue::get(NewTy);
  if (isa<ConstantAggregateZero>(C))
    return getVM()[V] = ConstantAggregateZero::get(NewTy);
  assert(isa<ConstantPointerNull>(C));
  return getVM()[V] = ConstantPointerNull::get(cast<PointerType>(NewTy));
}
bool SparcAsmPrinter::doFinalization(Module &M) {
  const TargetData *TD = TM.getTargetData();

  // Print out module-level global variables here.
  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I)
    if (I->hasInitializer()) {   // External global require no code
      // Check to see if this is a special global used by LLVM, if so, emit it.
      if (EmitSpecialLLVMGlobal(I))
        continue;
      
      O << "\n\n";
      std::string name = Mang->getValueName(I);
      Constant *C = I->getInitializer();
      unsigned Size = TD->getTypeSize(C->getType());
      unsigned Align = TD->getPrefTypeAlignment(C->getType());

      if (C->isNullValue() &&
          (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
           I->hasWeakLinkage() /* FIXME: Verify correct */)) {
        SwitchToDataSection(".data", I);
        if (I->hasInternalLinkage())
          O << "\t.local " << name << "\n";

        O << "\t.comm " << name << "," << TD->getTypeSize(C->getType())
          << "," << Align;
        O << "\n";
      } else {
        switch (I->getLinkage()) {
        case GlobalValue::LinkOnceLinkage:
        case GlobalValue::WeakLinkage:   // FIXME: Verify correct for weak.
          // Nonnull linkonce -> weak
          O << "\t.weak " << name << "\n";
          SwitchToDataSection("", I);
          O << "\t.section\t\".llvm.linkonce.d." << name
            << "\",\"aw\",@progbits\n";
          break;

        case GlobalValue::AppendingLinkage:
          // FIXME: appending linkage variables should go into a section of
          // their name or something.  For now, just emit them as external.
        case GlobalValue::ExternalLinkage:
          // If external or appending, declare as a global symbol
          O << "\t.globl " << name << "\n";
          // FALL THROUGH
        case GlobalValue::InternalLinkage:
          if (C->isNullValue())
            SwitchToDataSection(".bss", I);
          else
            SwitchToDataSection(".data", I);
          break;
        case GlobalValue::GhostLinkage:
          cerr << "Should not have any unmaterialized functions!\n";
          abort();
        case GlobalValue::DLLImportLinkage:
          cerr << "DLLImport linkage is not supported by this target!\n";
          abort();
        case GlobalValue::DLLExportLinkage:
          cerr << "DLLExport linkage is not supported by this target!\n";
          abort();
        default:
          assert(0 && "Unknown linkage type!");          
        }

        O << "\t.align " << Align << "\n";
        O << "\t.type " << name << ",#object\n";
        O << "\t.size " << name << "," << Size << "\n";
        O << name << ":\n";
        EmitGlobalConstant(C);
      }
    }

  AsmPrinter::doFinalization(M);
  return false; // success
}