Ejemplo n.º 1
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, "");
}
Ejemplo n.º 2
0
void StrPrinter::bvisit(const Constant &x) {
    str_ = x.get_name();
}
Ejemplo n.º 3
0
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->getABITypeSize(C->getType());
      unsigned Align = TD->getPreferredAlignment(I);

      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->getABITypeSize(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);
      }
    }

  return AsmPrinter::doFinalization(M);
}
Ejemplo n.º 4
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.begin(), args.end(),
                                        "", 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 = ConstantArray::get(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[0], 2);
        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
          const 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.begin(),
                             ResolverArgs.end(), "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(),
                                             "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.begin(), Args.end(), "", DoCallBB);
            ReturnInst::Create(F->getContext(), DoCallBB);
          } else {
            CallInst *Call = CallInst::Create(FuncPtr, Args.begin(), Args.end(),
                                              "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();
  }
}
Ejemplo n.º 5
0
 inline Value::Value(const Type& aType, const Constant& val,    const char* name)
     : fpImpl( SFun_Value_ctor_T_C_d_c(aType.getImpl(), val.getImpl(), name) )
 {
     verify(fpImpl);
 }
Ejemplo n.º 6
0
Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags,
                      ValueMapTypeRemapper *TypeMapper,
                      ValueMaterializer *Materializer) {
  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;
  
  // If we have a materializer and it can materialize a value, use that.
  if (Materializer) {
    if (Value *NewV = Materializer->materializeValueFor(const_cast<Value*>(V)))
      return VM[V] = NewV;
  }

  // Global values do not need to be seeded into the VM if they
  // are using the identity mapping.
  if (isa<GlobalValue>(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 auto *MDV = dyn_cast<MetadataAsValue>(V)) {
    const Metadata *MD = MDV->getMetadata();
    // If this is a module-level metadata and we know that nothing at the module
    // level is changing, then use an identity mapping.
    if (!isa<LocalAsMetadata>(MD) && (Flags & RF_NoModuleLevelChanges))
      return VM[V] = const_cast<Value *>(V);

    auto *MappedMD = MapMetadata(MD, VM, Flags, TypeMapper, Materializer);
    if (MD == MappedMD || (!MappedMD && (Flags & RF_IgnoreMissingEntries)))
      return VM[V] = const_cast<Value *>(V);

    // FIXME: This assert crashes during bootstrap, but I think it should be
    // correct.  For now, just match behaviour from before the metadata/value
    // split.
    //
    //    assert(MappedMD && "Referenced metadata value not in value map");
    return VM[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)) {
    Function *F = 
      cast<Function>(MapValue(BA->getFunction(), VM, Flags, TypeMapper, Materializer));
    BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(), VM,
                                                       Flags, TypeMapper, Materializer));
    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 = nullptr;
  for (; OpNo != NumOperands; ++OpNo) {
    Value *Op = C->getOperand(OpNo);
    Mapped = MapValue(Op, VM, Flags, TypeMapper, Materializer);
    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, Materializer));
  }
  
  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));
}
static bool match_index_and_scale(Instruction*  instr,
                                  Instruction** index,
                                  int*          log2_scale,
                                  Instruction** instr_to_unpin) {
  *instr_to_unpin = NULL;

  // Skip conversion ops
  Convert* convert = instr->as_Convert();
  if (convert != NULL) {
    instr = convert->value();
  }

  ShiftOp* shift = instr->as_ShiftOp();
  if (shift != NULL) {
    if (shift->is_pinned()) {
      *instr_to_unpin = shift;
    }
    // Constant shift value?
    Constant* con = shift->y()->as_Constant();
    if (con == NULL) return false;
    // Well-known type and value?
    IntConstant* val = con->type()->as_IntConstant();
    if (val == NULL) return false;
    if (shift->x()->type() != intType) return false;
    *index = shift->x();
    int tmp_scale = val->value();
    if (tmp_scale >= 0 && tmp_scale < 4) {
      *log2_scale = tmp_scale;
      return true;
    } else {
      return false;
    }
  }

  ArithmeticOp* arith = instr->as_ArithmeticOp();
  if (arith != NULL) {
    if (arith->is_pinned()) {
      *instr_to_unpin = arith;
    }
    // Check for integer multiply
    if (arith->op() == Bytecodes::_imul) {
      // See if either arg is a known constant
      Constant* con = arith->x()->as_Constant();
      if (con != NULL) {
        *index = arith->y();
      } else {
        con = arith->y()->as_Constant();
        if (con == NULL) return false;
        *index = arith->x();
      }
      if ((*index)->type() != intType) return false;
      // Well-known type and value?
      IntConstant* val = con->type()->as_IntConstant();
      if (val == NULL) return false;
      switch (val->value()) {
      case 1: *log2_scale = 0; return true;
      case 2: *log2_scale = 1; return true;
      case 4: *log2_scale = 2; return true;
      case 8: *log2_scale = 3; return true;
      default:            return false;
      }
    }
  }

  // Unknown instruction sequence; don't touch it
  return false;
}
Ejemplo n.º 8
0
Function* TranslationContext::createFunction(Executable& executable, uint64_t baseAddress)
{
	Function* fn = functionMap->createFunction(baseAddress);
	assert(fn != nullptr);
	
	auto targetInfo = TargetInfo::getTargetInfo(*module);
	AddressToBlock blockMap(*fn);
	BasicBlock* entry = &fn->back();
	TranslationCloningDirector director(*module, *functionMap, blockMap);
	
	Argument* registers = fn->arg_begin();
	auto flags = new AllocaInst(irgen->getFlagsTy(), "flags", entry);
	
	ArrayRef<Value*> ipGepIndices = irgen->getIpOffset();
	auto ipPointer = GetElementPtrInst::CreateInBounds(registers, ipGepIndices, "", entry);
	Type* ipType = GetElementPtrInst::getIndexedType(irgen->getRegisterTy(), ipGepIndices);
	
	Function* prologue = irgen->implementationForPrologue();
	inlineFunction(fn, prologue, { configVariable, registers }, director, baseAddress);
	
	uint64_t addressToDisassemble;
	auto end = executable.end();
	auto inst = cs->alloc();
	SmallVector<Value*, 4> inliningParameters = { configVariable, nullptr, registers, flags };
	while (blockMap.getOneStub(addressToDisassemble))
	{
		if (auto begin = executable.map(addressToDisassemble))
		if (cs->disassemble(inst.get(), begin, end, addressToDisassemble))
		if (BasicBlock* thisBlock = blockMap.implementInstruction(inst->address)) // already implemented?
		{
			// store instruction pointer
			// (this needs to be the IP of the next instruction)
			auto nextInstAddress = inst->address + inst->size;
			auto ipValue = ConstantInt::get(ipType, nextInstAddress);
			new StoreInst(ipValue, ipPointer, false, thisBlock);
			
			if (Function* implementation = irgen->implementationFor(inst->id))
			{
				// We have an implementation: inline it
				Constant* detailAsConstant = irgen->constantForDetail(*inst->detail);
				inliningParameters[1] = new GlobalVariable(*module, detailAsConstant->getType(), true, GlobalValue::PrivateLinkage, detailAsConstant);
				inlineFunction(fn, implementation, inliningParameters, director, nextInstAddress);
			}
			else
			{
				createAsmCall(*targetInfo, *inst, registers, *thisBlock);
				BasicBlock* target = blockMap.blockToInstruction(nextInstAddress);
				BranchInst::Create(target, thisBlock);
			}
			continue;
		}
		break;
	}
	
#if DEBUG && 0
	// check that it still works
	if (verifyModule(*module, &errs()))
	{
		module->dump();
		abort();
	}
#endif
	
	return fn;
}
/// getKindForGlobal - This is a top-level target-independent classifier for
/// a global variable.  Given an global variable and information from TM, it
/// classifies the global in a variety of ways that make various target
/// implementations simpler.  The target implementation is free to ignore this
/// extra info of course.
SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV,
                                                       const TargetMachine &TM){
  assert(!GV->isDeclaration() && !GV->hasAvailableExternallyLinkage() &&
         "Can only be used for global definitions");

  Reloc::Model ReloModel = TM.getRelocationModel();

  // Early exit - functions should be always in text sections.
  const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
  if (GVar == 0)
    return SectionKind::getText();

  // Handle thread-local data first.
  if (GVar->isThreadLocal()) {
    if (isSuitableForBSS(GVar))
      return SectionKind::getThreadBSS();
    return SectionKind::getThreadData();
  }

  // Variables with common linkage always get classified as common.
  if (GVar->hasCommonLinkage())
    return SectionKind::getCommon();

  // Variable can be easily put to BSS section.
  if (isSuitableForBSS(GVar)) {
    if (GVar->hasLocalLinkage())
      return SectionKind::getBSSLocal();
    else if (GVar->hasExternalLinkage())
      return SectionKind::getBSSExtern();
    return SectionKind::getBSS();
  }

  Constant *C = GVar->getInitializer();

  // If the global is marked constant, we can put it into a mergable section,
  // a mergable string section, or general .data if it contains relocations.
  if (GVar->isConstant()) {
    // If the initializer for the global contains something that requires a
    // relocation, then we may have to drop this into a wriable data section
    // even though it is marked const.
    switch (C->getRelocationInfo()) {
    default: assert(0 && "unknown relocation info kind");
    case Constant::NoRelocation:
      // If initializer is a null-terminated string, put it in a "cstring"
      // section of the right width.
      if (const ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) {
        if (const IntegerType *ITy =
              dyn_cast<IntegerType>(ATy->getElementType())) {
          if ((ITy->getBitWidth() == 8 || ITy->getBitWidth() == 16 ||
               ITy->getBitWidth() == 32) &&
              IsNullTerminatedString(C)) {
            if (ITy->getBitWidth() == 8)
              return SectionKind::getMergeable1ByteCString();
            if (ITy->getBitWidth() == 16)
              return SectionKind::getMergeable2ByteCString();

            assert(ITy->getBitWidth() == 32 && "Unknown width");
            return SectionKind::getMergeable4ByteCString();
          }
        }
      }

      // Otherwise, just drop it into a mergable constant section.  If we have
      // a section for this size, use it, otherwise use the arbitrary sized
      // mergable section.
      switch (TM.getTargetData()->getTypeAllocSize(C->getType())) {
      case 4:  return SectionKind::getMergeableConst4();
      case 8:  return SectionKind::getMergeableConst8();
      case 16: return SectionKind::getMergeableConst16();
      default: return SectionKind::getMergeableConst();
      }

    case Constant::LocalRelocation:
      // In static relocation model, the linker will resolve all addresses, so
      // the relocation entries will actually be constants by the time the app
      // starts up.  However, we can't put this into a mergable section, because
      // the linker doesn't take relocations into consideration when it tries to
      // merge entries in the section.
      if (ReloModel == Reloc::Static)
        return SectionKind::getReadOnly();

      // Otherwise, the dynamic linker needs to fix it up, put it in the
      // writable data.rel.local section.
      return SectionKind::getReadOnlyWithRelLocal();

    case Constant::GlobalRelocations:
      // In static relocation model, the linker will resolve all addresses, so
      // the relocation entries will actually be constants by the time the app
      // starts up.  However, we can't put this into a mergable section, because
      // the linker doesn't take relocations into consideration when it tries to
      // merge entries in the section.
      if (ReloModel == Reloc::Static)
        return SectionKind::getReadOnly();

      // Otherwise, the dynamic linker needs to fix it up, put it in the
      // writable data.rel section.
      return SectionKind::getReadOnlyWithRel();
    }
  }

  // Okay, this isn't a constant.  If the initializer for the global is going
  // to require a runtime relocation by the dynamic linker, put it into a more
  // specific section to improve startup time of the app.  This coalesces these
  // globals together onto fewer pages, improving the locality of the dynamic
  // linker.
  if (ReloModel == Reloc::Static)
    return SectionKind::getDataNoRel();

  switch (C->getRelocationInfo()) {
  default: assert(0 && "unknown relocation info kind");
  case Constant::NoRelocation:
    return SectionKind::getDataNoRel();
  case Constant::LocalRelocation:
    return SectionKind::getDataRelLocal();
  case Constant::GlobalRelocations:
    return SectionKind::getDataRel();
  }
}
Ejemplo n.º 10
0
//
// Method: postOrderInline()
//
// Description:
//  This methods does a post order traversal of the call graph and performs
//  bottom-up inlining of the DSGraphs.
//
void
BUDataStructures::postOrderInline (Module & M) {
  // Variables used for Tarjan SCC-finding algorithm.  These are passed into
  // the recursive function used to find SCCs.
  std::vector<const Function*> Stack;
  std::map<const Function*, unsigned> ValMap;
  unsigned NextID = 1;


  // Do post order traversal on the global ctors. Use this information to update
  // the globals graph.
  const char *Name = "llvm.global_ctors";
  GlobalVariable *GV = M.getNamedGlobal(Name);
  if (GV && !(GV->isDeclaration()) && !(GV->hasLocalLinkage())) {
    // Should be an array of '{ int, void ()* }' structs.  The first value is
    // the init priority, which we ignore.
    ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
    if (InitList) {
      for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
        if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))) {
          if (CS->getNumOperands() != 2)
            break; // Not array of 2-element structs.
          Constant *FP = CS->getOperand(1);
          if (FP->isNullValue())
            break;  // Found a null terminator, exit.

          if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
            if (CE->isCast())
              FP = CE->getOperand(0);
          Function *F = dyn_cast<Function>(FP);
          if (F && !F->isDeclaration() && !ValMap.count(F)) {
            calculateGraphs(F, Stack, NextID, ValMap);
            CloneAuxIntoGlobal(getDSGraph(*F));
          }
        }
      GlobalsGraph->removeTriviallyDeadNodes();
      GlobalsGraph->maskIncompleteMarkers();

      // Mark external globals incomplete.
      GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals);
      GlobalsGraph->computeExternalFlags(DSGraph::DontMarkFormalsExternal);
      GlobalsGraph->computeIntPtrFlags();

      //
      // Create equivalence classes for aliasing globals so that we only need to
      // record one global per DSNode.
      //
      formGlobalECs();
      // propogte information calculated
      // from the globals graph to the other graphs.
      for (Module::iterator F = M.begin(); F != M.end(); ++F) {
        if (!(F->isDeclaration())){
          DSGraph *Graph  = getDSGraph(*F);
          cloneGlobalsInto(Graph, DSGraph::DontCloneCallNodes |
                           DSGraph::DontCloneAuxCallNodes);
          Graph->buildCallGraph(callgraph, GlobalFunctionList, filterCallees);
          Graph->maskIncompleteMarkers();
          Graph->markIncompleteNodes(DSGraph::MarkFormalArgs |
                                     DSGraph::IgnoreGlobals);
          Graph->computeExternalFlags(DSGraph::DontMarkFormalsExternal);
          Graph->computeIntPtrFlags();
        }
      }
    }
  }

  //
  // Start the post order traversal with the main() function.  If there is no
  // main() function, don't worry; we'll have a separate traversal for inlining
  // graphs for functions not reachable from main().
  //
  Function *MainFunc = M.getFunction ("main");
  if (MainFunc && !MainFunc->isDeclaration()) {
    calculateGraphs(MainFunc, Stack, NextID, ValMap);
    CloneAuxIntoGlobal(getDSGraph(*MainFunc));
  }

  //
  // Calculate the graphs for any functions that are unreachable from main...
  //
  for (Function &F : M)
    if (!F.isDeclaration() && !ValMap.count(&F)) {
      if (MainFunc)
        DEBUG(errs() << debugname << ": Function unreachable from main: "
        << F.getName() << "\n");
      calculateGraphs(&F, Stack, NextID, ValMap);     // Calculate all graphs.
      CloneAuxIntoGlobal(getDSGraph(F));

      // Mark this graph as processed.  Do this by finding all functions
      // in the graph that map to it, and mark them visited.
      // Note that this really should be handled neatly by calculateGraphs
      // itself, not here.  However this catches the worst offenders.
      DSGraph *G = getDSGraph(F);
      for(DSGraph::retnodes_iterator RI = G->retnodes_begin(),
          RE = G->retnodes_end(); RI != RE; ++RI) {
        if (getDSGraph(*RI->first) == G) {
          if (!ValMap.count(RI->first))
            ValMap[RI->first] = ~0U;
          else
            assert(ValMap[RI->first] == ~0U);
        }
      }
    }
  return;
}
Ejemplo n.º 11
0
/// getPredicateOnEdge - Determine whether the specified value comparison
/// with a constant is known to be true or false on the specified CFG edge.
/// Pred is a CmpInst predicate.
LazyValueInfo::Tristate
LazyValueInfo::getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
                                  BasicBlock *FromBB, BasicBlock *ToBB) {
  LVILatticeVal Result = getCache(PImpl).getValueOnEdge(V, FromBB, ToBB);
  
  // If we know the value is a constant, evaluate the conditional.
  Constant *Res = 0;
  if (Result.isConstant()) {
    Res = ConstantFoldCompareInstOperands(Pred, Result.getConstant(), C, TD,
                                          TLI);
    if (ConstantInt *ResCI = dyn_cast<ConstantInt>(Res))
      return ResCI->isZero() ? False : True;
    return Unknown;
  }
  
  if (Result.isConstantRange()) {
    ConstantInt *CI = dyn_cast<ConstantInt>(C);
    if (!CI) return Unknown;
    
    ConstantRange CR = Result.getConstantRange();
    if (Pred == ICmpInst::ICMP_EQ) {
      if (!CR.contains(CI->getValue()))
        return False;
      
      if (CR.isSingleElement() && CR.contains(CI->getValue()))
        return True;
    } else if (Pred == ICmpInst::ICMP_NE) {
      if (!CR.contains(CI->getValue()))
        return True;
      
      if (CR.isSingleElement() && CR.contains(CI->getValue()))
        return False;
    }
    
    // Handle more complex predicates.
    ConstantRange TrueValues =
        ICmpInst::makeConstantRange((ICmpInst::Predicate)Pred, CI->getValue());
    if (TrueValues.contains(CR))
      return True;
    if (TrueValues.inverse().contains(CR))
      return False;
    return Unknown;
  }
  
  if (Result.isNotConstant()) {
    // If this is an equality comparison, we can try to fold it knowing that
    // "V != C1".
    if (Pred == ICmpInst::ICMP_EQ) {
      // !C1 == C -> false iff C1 == C.
      Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE,
                                            Result.getNotConstant(), C, TD,
                                            TLI);
      if (Res->isNullValue())
        return False;
    } else if (Pred == ICmpInst::ICMP_NE) {
      // !C1 != C -> true iff C1 == C.
      Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE,
                                            Result.getNotConstant(), C, TD,
                                            TLI);
      if (Res->isNullValue())
        return True;
    }
    return Unknown;
  }
  
  return Unknown;
}
Ejemplo n.º 12
0
PreservedAnalyses GlobalDCEPass::run(Module &M, ModuleAnalysisManager &) {
  bool Changed = false;

  // Remove empty functions from the global ctors list.
  Changed |= optimizeGlobalCtorsList(M, isEmptyFunction);

  // Collect the set of members for each comdat.
  for (Function &F : M)
    if (Comdat *C = F.getComdat())
      ComdatMembers.insert(std::make_pair(C, &F));
  for (GlobalVariable &GV : M.globals())
    if (Comdat *C = GV.getComdat())
      ComdatMembers.insert(std::make_pair(C, &GV));
  for (GlobalAlias &GA : M.aliases())
    if (Comdat *C = GA.getComdat())
      ComdatMembers.insert(std::make_pair(C, &GA));

  // Loop over the module, adding globals which are obviously necessary.
  for (GlobalObject &GO : M.global_objects()) {
    Changed |= RemoveUnusedGlobalValue(GO);
    // Functions with external linkage are needed if they have a body.
    // Externally visible & appending globals are needed, if they have an
    // initializer.
    if (!GO.isDeclaration() && !GO.hasAvailableExternallyLinkage())
      if (!GO.isDiscardableIfUnused())
        GlobalIsNeeded(&GO);
  }

  for (GlobalAlias &GA : M.aliases()) {
    Changed |= RemoveUnusedGlobalValue(GA);
    // Externally visible aliases are needed.
    if (!GA.isDiscardableIfUnused())
      GlobalIsNeeded(&GA);
  }

  for (GlobalIFunc &GIF : M.ifuncs()) {
    Changed |= RemoveUnusedGlobalValue(GIF);
    // Externally visible ifuncs are needed.
    if (!GIF.isDiscardableIfUnused())
      GlobalIsNeeded(&GIF);
  }

  // Now that all globals which are needed are in the AliveGlobals set, we loop
  // through the program, deleting those which are not alive.
  //

  // The first pass is to drop initializers of global variables which are dead.
  std::vector<GlobalVariable *> DeadGlobalVars; // Keep track of dead globals
  for (GlobalVariable &GV : M.globals())
    if (!AliveGlobals.count(&GV)) {
      DeadGlobalVars.push_back(&GV);         // Keep track of dead globals
      if (GV.hasInitializer()) {
        Constant *Init = GV.getInitializer();
        GV.setInitializer(nullptr);
        if (isSafeToDestroyConstant(Init))
          Init->destroyConstant();
      }
    }

  // The second pass drops the bodies of functions which are dead...
  std::vector<Function *> DeadFunctions;
  for (Function &F : M)
    if (!AliveGlobals.count(&F)) {
      DeadFunctions.push_back(&F);         // Keep track of dead globals
      if (!F.isDeclaration())
        F.deleteBody();
    }

  // The third pass drops targets of aliases which are dead...
  std::vector<GlobalAlias*> DeadAliases;
  for (GlobalAlias &GA : M.aliases())
    if (!AliveGlobals.count(&GA)) {
      DeadAliases.push_back(&GA);
      GA.setAliasee(nullptr);
    }

  // The third pass drops targets of ifuncs which are dead...
  std::vector<GlobalIFunc*> DeadIFuncs;
  for (GlobalIFunc &GIF : M.ifuncs())
    if (!AliveGlobals.count(&GIF)) {
      DeadIFuncs.push_back(&GIF);
      GIF.setResolver(nullptr);
    }

  // Now that all interferences have been dropped, delete the actual objects
  // themselves.
  auto EraseUnusedGlobalValue = [&](GlobalValue *GV) {
    RemoveUnusedGlobalValue(*GV);
    GV->eraseFromParent();
    Changed = true;
  };

  NumFunctions += DeadFunctions.size();
  for (Function *F : DeadFunctions)
    EraseUnusedGlobalValue(F);

  NumVariables += DeadGlobalVars.size();
  for (GlobalVariable *GV : DeadGlobalVars)
    EraseUnusedGlobalValue(GV);

  NumAliases += DeadAliases.size();
  for (GlobalAlias *GA : DeadAliases)
    EraseUnusedGlobalValue(GA);

  NumIFuncs += DeadIFuncs.size();
  for (GlobalIFunc *GIF : DeadIFuncs)
    EraseUnusedGlobalValue(GIF);

  // Make sure that all memory is released
  AliveGlobals.clear();
  SeenConstants.clear();
  ComdatMembers.clear();

  if (Changed)
    return PreservedAnalyses::none();
  return PreservedAnalyses::all();
}
Ejemplo n.º 13
0
bool GlobalDCE::runOnModule(Module &M) {
  bool Changed = false;

  // Remove empty functions from the global ctors list.
  Changed |= optimizeGlobalCtorsList(M, isEmptyFunction);

  // Loop over the module, adding globals which are obviously necessary.
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    Changed |= RemoveUnusedGlobalValue(*I);
    // Functions with external linkage are needed if they have a body
    if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage()) {
      if (!I->isDiscardableIfUnused())
        GlobalIsNeeded(I);
    }
  }

  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I) {
    Changed |= RemoveUnusedGlobalValue(*I);
    // Externally visible & appending globals are needed, if they have an
    // initializer.
    if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage()) {
      if (!I->isDiscardableIfUnused())
        GlobalIsNeeded(I);
    }
  }

  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
       I != E; ++I) {
    Changed |= RemoveUnusedGlobalValue(*I);
    // Externally visible aliases are needed.
    if (!I->isDiscardableIfUnused()) {
      GlobalIsNeeded(I);
    }
  }

  // Now that all globals which are needed are in the AliveGlobals set, we loop
  // through the program, deleting those which are not alive.
  //

  // The first pass is to drop initializers of global variables which are dead.
  std::vector<GlobalVariable*> DeadGlobalVars;   // Keep track of dead globals
  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I)
    if (!AliveGlobals.count(I)) {
      DeadGlobalVars.push_back(I);         // Keep track of dead globals
      if (I->hasInitializer()) {
        Constant *Init = I->getInitializer();
        I->setInitializer(nullptr);
        if (isSafeToDestroyConstant(Init))
          Init->destroyConstant();
      }
    }

  // The second pass drops the bodies of functions which are dead...
  std::vector<Function*> DeadFunctions;
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!AliveGlobals.count(I)) {
      DeadFunctions.push_back(I);         // Keep track of dead globals
      if (!I->isDeclaration())
        I->deleteBody();
    }

  // The third pass drops targets of aliases which are dead...
  std::vector<GlobalAlias*> DeadAliases;
  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;
       ++I)
    if (!AliveGlobals.count(I)) {
      DeadAliases.push_back(I);
      I->setAliasee(nullptr);
    }

  if (!DeadFunctions.empty()) {
    // Now that all interferences have been dropped, delete the actual objects
    // themselves.
    for (unsigned i = 0, e = DeadFunctions.size(); i != e; ++i) {
      RemoveUnusedGlobalValue(*DeadFunctions[i]);
      M.getFunctionList().erase(DeadFunctions[i]);
    }
    NumFunctions += DeadFunctions.size();
    Changed = true;
  }

  if (!DeadGlobalVars.empty()) {
    for (unsigned i = 0, e = DeadGlobalVars.size(); i != e; ++i) {
      RemoveUnusedGlobalValue(*DeadGlobalVars[i]);
      M.getGlobalList().erase(DeadGlobalVars[i]);
    }
    NumVariables += DeadGlobalVars.size();
    Changed = true;
  }

  // Now delete any dead aliases.
  if (!DeadAliases.empty()) {
    for (unsigned i = 0, e = DeadAliases.size(); i != e; ++i) {
      RemoveUnusedGlobalValue(*DeadAliases[i]);
      M.getAliasList().erase(DeadAliases[i]);
    }
    NumAliases += DeadAliases.size();
    Changed = true;
  }

  // Make sure that all memory is released
  AliveGlobals.clear();
  SeenConstants.clear();

  return Changed;
}
bool WebAssemblyLowerEmscriptenEHSjLj::runEHOnFunction(Function &F) {
  Module &M = *F.getParent();
  LLVMContext &C = F.getContext();
  IRBuilder<> IRB(C);
  bool Changed = false;
  SmallVector<Instruction *, 64> ToErase;
  SmallPtrSet<LandingPadInst *, 32> LandingPads;
  bool AllowExceptions =
      areAllExceptionsAllowed() || EHWhitelistSet.count(F.getName());

  for (BasicBlock &BB : F) {
    auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
    if (!II)
      continue;
    Changed = true;
    LandingPads.insert(II->getLandingPadInst());
    IRB.SetInsertPoint(II);

    bool NeedInvoke = AllowExceptions && canThrow(II->getCalledValue());
    if (NeedInvoke) {
      // Wrap invoke with invoke wrapper and generate preamble/postamble
      Value *Threw = wrapInvoke(II);
      ToErase.push_back(II);

      // Insert a branch based on __THREW__ variable
      Value *Cmp = IRB.CreateICmpEQ(Threw, IRB.getInt32(1), "cmp");
      IRB.CreateCondBr(Cmp, II->getUnwindDest(), II->getNormalDest());

    } else {
      // This can't throw, and we don't need this invoke, just replace it with a
      // call+branch
      SmallVector<Value *, 16> Args(II->arg_begin(), II->arg_end());
      CallInst *NewCall = IRB.CreateCall(II->getCalledValue(), Args);
      NewCall->takeName(II);
      NewCall->setCallingConv(II->getCallingConv());
      NewCall->setDebugLoc(II->getDebugLoc());
      NewCall->setAttributes(II->getAttributes());
      II->replaceAllUsesWith(NewCall);
      ToErase.push_back(II);

      IRB.CreateBr(II->getNormalDest());

      // Remove any PHI node entries from the exception destination
      II->getUnwindDest()->removePredecessor(&BB);
    }
  }

  // Process resume instructions
  for (BasicBlock &BB : F) {
    // Scan the body of the basic block for resumes
    for (Instruction &I : BB) {
      auto *RI = dyn_cast<ResumeInst>(&I);
      if (!RI)
        continue;

      // Split the input into legal values
      Value *Input = RI->getValue();
      IRB.SetInsertPoint(RI);
      Value *Low = IRB.CreateExtractValue(Input, 0, "low");
      // Create a call to __resumeException function
      IRB.CreateCall(ResumeF, {Low});
      // Add a terminator to the block
      IRB.CreateUnreachable();
      ToErase.push_back(RI);
    }
  }

  // Process llvm.eh.typeid.for intrinsics
  for (BasicBlock &BB : F) {
    for (Instruction &I : BB) {
      auto *CI = dyn_cast<CallInst>(&I);
      if (!CI)
        continue;
      const Function *Callee = CI->getCalledFunction();
      if (!Callee)
        continue;
      if (Callee->getIntrinsicID() != Intrinsic::eh_typeid_for)
        continue;

      IRB.SetInsertPoint(CI);
      CallInst *NewCI =
          IRB.CreateCall(EHTypeIDF, CI->getArgOperand(0), "typeid");
      CI->replaceAllUsesWith(NewCI);
      ToErase.push_back(CI);
    }
  }

  // Look for orphan landingpads, can occur in blocks with no predecessors
  for (BasicBlock &BB : F) {
    Instruction *I = BB.getFirstNonPHI();
    if (auto *LPI = dyn_cast<LandingPadInst>(I))
      LandingPads.insert(LPI);
  }

  // Handle all the landingpad for this function together, as multiple invokes
  // may share a single lp
  for (LandingPadInst *LPI : LandingPads) {
    IRB.SetInsertPoint(LPI);
    SmallVector<Value *, 16> FMCArgs;
    for (unsigned i = 0, e = LPI->getNumClauses(); i < e; ++i) {
      Constant *Clause = LPI->getClause(i);
      // As a temporary workaround for the lack of aggregate varargs support
      // in the interface between JS and wasm, break out filter operands into
      // their component elements.
      if (LPI->isFilter(i)) {
        auto *ATy = cast<ArrayType>(Clause->getType());
        for (unsigned j = 0, e = ATy->getNumElements(); j < e; ++j) {
          Value *EV = IRB.CreateExtractValue(Clause, makeArrayRef(j), "filter");
          FMCArgs.push_back(EV);
        }
      } else
        FMCArgs.push_back(Clause);
    }

    // Create a call to __cxa_find_matching_catch_N function
    Function *FMCF = getFindMatchingCatch(M, FMCArgs.size());
    CallInst *FMCI = IRB.CreateCall(FMCF, FMCArgs, "fmc");
    Value *Undef = UndefValue::get(LPI->getType());
    Value *Pair0 = IRB.CreateInsertValue(Undef, FMCI, 0, "pair0");
    Value *TempRet0 =
        IRB.CreateLoad(TempRet0GV, TempRet0GV->getName() + ".val");
    Value *Pair1 = IRB.CreateInsertValue(Pair0, TempRet0, 1, "pair1");

    LPI->replaceAllUsesWith(Pair1);
    ToErase.push_back(LPI);
  }

  // Erase everything we no longer need in this function
  for (Instruction *I : ToErase)
    I->eraseFromParent();

  return Changed;
}
Ejemplo n.º 15
0
bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable *> &Globals,
                          const BitVector &GlobalSet, Module &M, bool isConst,
                          unsigned AddrSpace) const {

  Type *Int32Ty = Type::getInt32Ty(M.getContext());
  auto &DL = M.getDataLayout();

  assert(Globals.size() > 1);

  DEBUG(dbgs() << " Trying to merge set, starts with #"
               << GlobalSet.find_first() << "\n");

  ssize_t i = GlobalSet.find_first();
  while (i != -1) {
    ssize_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 != -1; j = GlobalSet.find_next(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;

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

    // 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.
    GlobalVariable *MergedGV = new GlobalVariable(
        M, MergedTy, isConst, Linkage, MergedInit,
        HasExternal ? "_MergedGlobals_" + TheFirstExternal->getName()
                    : "_MergedGlobals",
        nullptr, GlobalVariable::NotThreadLocal, AddrSpace);

    for (ssize_t k = i, idx = 0; k != j; k = GlobalSet.find_next(k)) {
      GlobalValue::LinkageTypes Linkage = Globals[k]->getLinkage();
      std::string Name = Globals[k]->getName();

      Constant *Idx[2] = {
        ConstantInt::get(Int32Ty, 0),
        ConstantInt::get(Int32Ty, idx++)
      };
      Constant *GEP =
          ConstantExpr::getInBoundsGetElementPtr(MergedTy, 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, Linkage, Name, GEP, &M);
      }

      NumMerged++;
    }
    i = j;
  }

  return true;
}
 void VisitConstant(const Constant& c) {
   value_map_[&c] = c.GetValue();
 }
Ejemplo n.º 17
0
bool SDFix::fixDestructors() {
  bool replaced = false;

  for (GlobalVariable& gv : module->getGlobalList()) {
    if (! sd_isVtableName_ref(gv.getName()))
      continue;
    else if (! gv.hasInitializer())
      continue;

    Constant* init = gv.getInitializer();
    assert(init);
    ConstantArray* vtable = dyn_cast<ConstantArray>(init);
    assert(vtable);

    // get an idea about the virtual function regions
    std::vector<vtbl_pair_t> vtblRegions = findSubVtables(vtable);

    // for each subvtable
    for(unsigned vtblInd = 0; vtblInd < vtblRegions.size(); vtblInd++) {
      // record the destructors used in the vtable
      std::vector<DestructorInfo> destructors(3);

      vtbl_pair_t p = vtblRegions[vtblInd];

      for(unsigned i=p.first; i<p.second; i++) {
        Constant* destructor = sd_getDestructorFunction(vtable->getOperand(i));

        if (destructor == NULL)
          continue;

        // get the type from its name
        unsigned s = destructor->getName().size();
        char type = destructor->getName()[s-3];
        assert('0' <= type && type <= '2');
        unsigned typeInt = type - '0';

        // store it temporarily
        destructors[typeInt] = DestructorInfo(destructor, i);
      }

      // deleting destructor should always be defined
      assert(! destructors[0].needsReplacement());

      DestructorInfo* d1 = &destructors[1];
      DestructorInfo* d2 = &destructors[2];

      // only one of the rest could be undefined
      assert(! d1->needsReplacement() || ! d2->needsReplacement());

      // if complete object destructor is missing...
      if (d1->needsReplacement()) {
        std::string gv2Name = d1->function->getName();
        unsigned l = gv2Name.length();
        gv2Name = gv2Name.replace(l-3, 1, "2");

        Function* f1 = d1->getFunction();
        assert(f1);
        Function* f2 = module->getFunction(gv2Name);
        assert(f2);

        sd_print("Replacing %s with %s inside %s\n",
                 d1->function->getName().data(),
                 gv2Name.c_str(),
                 gv.getName().data());

        f1->replaceAllUsesWith(f2);
        replaced = true;

      // if base object destructor is missing...
      } else if (d2->needsReplacement()) {
        std::string gv1Name = d2->function->getName();
        unsigned l = gv1Name.length();
        gv1Name = gv1Name.replace(l-3, 1, "1");

        Function* f2 = d2->getFunction();
        assert(f2);
        Function* f1 = module->getFunction(gv1Name);
        assert(f1);

        sd_print("Replacing %s with %s inside %s\n",
                 d2->function->getName().data(),
                 gv1Name.c_str(),
                 gv.getName().data());

        f2->replaceAllUsesWith(f1);
        replaced = true;
      }
    }
  }

  return replaced;
}
 void VisitConstant(const Constant& c) {
   std::ostringstream ss;
   ss << c.GetValue();
   value_map_[&c] = ss.str();
 }
Ejemplo n.º 19
0
/// Given a disjoint set of bitsets and globals, layout the globals, build the
/// bit sets and lower the llvm.bitset.test calls.
void LowerBitSets::buildBitSetsFromGlobalVariables(
    ArrayRef<Metadata *> BitSets, ArrayRef<GlobalVariable *> Globals) {
  // Build a new global with the combined contents of the referenced globals.
  // This global is a struct whose even-indexed elements contain the original
  // contents of the referenced globals and whose odd-indexed elements contain
  // any padding required to align the next element to the next power of 2.
  std::vector<Constant *> GlobalInits;
  const DataLayout &DL = M->getDataLayout();
  for (GlobalVariable *G : Globals) {
    GlobalInits.push_back(G->getInitializer());
    uint64_t InitSize = DL.getTypeAllocSize(G->getValueType());

    // Compute the amount of padding required.
    uint64_t Padding = NextPowerOf2(InitSize - 1) - InitSize;

    // Cap at 128 was found experimentally to have a good data/instruction
    // overhead tradeoff.
    if (Padding > 128)
      Padding = RoundUpToAlignment(InitSize, 128) - InitSize;

    GlobalInits.push_back(
        ConstantAggregateZero::get(ArrayType::get(Int8Ty, Padding)));
  }
  if (!GlobalInits.empty())
    GlobalInits.pop_back();
  Constant *NewInit = ConstantStruct::getAnon(M->getContext(), GlobalInits);
  auto *CombinedGlobal =
      new GlobalVariable(*M, NewInit->getType(), /*isConstant=*/true,
                         GlobalValue::PrivateLinkage, NewInit);

  StructType *NewTy = cast<StructType>(NewInit->getType());
  const StructLayout *CombinedGlobalLayout = DL.getStructLayout(NewTy);

  // Compute the offsets of the original globals within the new global.
  DenseMap<GlobalObject *, uint64_t> GlobalLayout;
  for (unsigned I = 0; I != Globals.size(); ++I)
    // Multiply by 2 to account for padding elements.
    GlobalLayout[Globals[I]] = CombinedGlobalLayout->getElementOffset(I * 2);

  lowerBitSetCalls(BitSets, CombinedGlobal, GlobalLayout);

  // Build aliases pointing to offsets into the combined global for each
  // global from which we built the combined global, and replace references
  // to the original globals with references to the aliases.
  for (unsigned I = 0; I != Globals.size(); ++I) {
    // Multiply by 2 to account for padding elements.
    Constant *CombinedGlobalIdxs[] = {ConstantInt::get(Int32Ty, 0),
                                      ConstantInt::get(Int32Ty, I * 2)};
    Constant *CombinedGlobalElemPtr = ConstantExpr::getGetElementPtr(
        NewInit->getType(), CombinedGlobal, CombinedGlobalIdxs);
    if (LinkerSubsectionsViaSymbols) {
      Globals[I]->replaceAllUsesWith(CombinedGlobalElemPtr);
    } else {
      assert(Globals[I]->getType()->getAddressSpace() == 0);
      GlobalAlias *GAlias = GlobalAlias::create(NewTy->getElementType(I * 2), 0,
                                                Globals[I]->getLinkage(), "",
                                                CombinedGlobalElemPtr, M);
      GAlias->setVisibility(Globals[I]->getVisibility());
      GAlias->takeName(Globals[I]);
      Globals[I]->replaceAllUsesWith(GAlias);
    }
    Globals[I]->eraseFromParent();
  }
}
Ejemplo n.º 20
0
INLINE
Constant *Constant::dispatchMarshal(Stream &stream, JVM_U1 tag)
{
	Constant *constant = NULL;

	switch(tag)
	{
	case 7:
		constant = new ConstantClass();
		break;
	case 9:
		constant = new ConstantFieldRef();
		break;
	case 10:
		constant = new ConstantMethodRef();
		break;
	case 11:
		constant = new ConstantInterfaceMethodRef();
		break;
	case 8:
		constant = new ConstantString();
		break;
	case 3:
		constant = new ConstantInteger();
		break;
	case 4:
		constant = new ConstantFloat();
		break;
	case 5:
		constant = new ConstantLong();
		break;
	case 6:
		constant = new ConstantDouble();
		break;
	case 12:
		constant = new ConstantNameAndType();
		break;
	case 1:
		constant = new ConstantUtf8();
		break;
	case 15:
		constant = new ConstantMethodHandle();
		break;
	case 16:
		constant = new ConstantMethodType();
		break;
	case 18:
		constant = new ConstantInvokeDynamic();
		break;
	default:
		ERROR("tag is %d, this should not happened!", tag);
		break;
	}

	if(constant != NULL)
	{
		constant->tag_ = tag;
		if(constant->marshal(stream) == false)
		{
			ERROR("constant %d marshal failed! this constant object will be removed.", tag);
			delete constant;
			return NULL;
		}
	}
	return constant;
}
Ejemplo n.º 21
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));
  SanCovTracePCIndir =
      checkSanitizerInterfaceFunction(M.getOrInsertFunction(
          kSanCovTracePCIndir, VoidTy, IntptrTy, 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);

  SanCovTracePC = checkSanitizerInterfaceFunction(
      M.getOrInsertFunction(kSanCovTracePC, VoidTy, nullptr));
  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, alignTo(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;
}
Ejemplo n.º 22
0
  virtual bool runOnFunction(Function & F) {
 
    Module * M = F.getParent();  
    Function * func = &F; 
    string dataStr;
    Value * globalStringPtr;

    for(Function::iterator i = func->begin(), e = func->end(); i != e; ++i){ 

      BasicBlock * BB = &*i;
      for(auto & I : *BB){
        Instruction * inst = &I;
         if(CallInst * callInst = dyn_cast<CallInst>(&*inst)){
	  string name = callInst->getCalledFunction()->getName().str();
	  if(name == "substring"){

            if(debugPrint) errs()<<"substring = "<<*callInst<<"\n";
	    Value * startIndex = callInst->getOperand(1);
	    Value * endIndex = callInst->getOperand(2);
	    int startIdx;
	    int endIdx;

	    if(ConstantInt * constValue = dyn_cast<ConstantInt>(&*startIndex)){
	      if(debugPrint) errs()<<"constant1 = "<< constValue->getZExtValue() <<"\n";
	      startIdx = constValue->getZExtValue();
	    }
	    else{
              continue;
	    }

	    if(ConstantInt * constValue = dyn_cast<ConstantInt>(&*endIndex)){
	      if(debugPrint) errs()<<"constant2 = "<< constValue->getZExtValue() <<"\n";
	      endIdx = constValue->getZExtValue();
	    }
	    else{
              continue;
	    }
       
            globalStringPtr = callInst->getOperand(0); // get pointer to constant string
	    StringRef dataString;
	    if(!getConstantStringInfo(globalStringPtr, dataString)) // if argument not a constant string
              continue;

	    dataStr = dataString.str();     
	    char * sourceString = substring(dataStr.c_str(), startIdx, endIdx);
            if(debugPrint) errs()<<"sourceString = "<<sourceString<<"\n";

	    Constant * stringConstant = ConstantDataArray::getString(M->getContext(), StringRef(sourceString), true);
	    GlobalVariable * globalString = new GlobalVariable(*M, stringConstant->getType(), true, 
							       GlobalValue::ExternalLinkage, stringConstant, "");

            if(debugPrint) errs()<<"globalString = "<<*globalString<<"\n";
	    IntegerType * intTy = IntegerType::get(M->getContext(), 64);
	    ConstantInt * index1 = ConstantInt::get(intTy, 0);
	    vector<Value *> indxList;
	    indxList.push_back(index1);
	    indxList.push_back(index1);

	    GetElementPtrInst * stringPtr = GetElementPtrInst::Create(NULL, globalString, 
								      indxList, Twine(""), callInst);
	    replaceValues[callInst] = stringPtr; 	    
	  }
	}
      }
    }

    replaceUses(); 
    return true;

  }
Ejemplo n.º 23
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));
}
Ejemplo n.º 24
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 (auto *FoldedPtr = ConstantFoldConstant(Ptr, DL, TLI)) {
        DEBUG(dbgs() << "Folding constant ptr expression: " << *Ptr);
        Ptr = FoldedPtr;
        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 (auto *FoldedPtr = ConstantFoldConstant(Ptr, DL, TLI))
                Ptr = FoldedPtr;

            // 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 (auto *FoldedPtr = ConstantFoldConstant(Ptr, DL, TLI)) {
        Ptr = FoldedPtr;
        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->isMinusOne() &&
                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->isInterposable()) {
        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(CS, 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 (auto *FoldedInstResult = ConstantFoldConstant(InstResult, DL, TLI))
        InstResult = FoldedInstResult;

      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;
  }
}
Ejemplo n.º 25
0
/// getFeasibleSuccessors - Return a vector of booleans to indicate which
/// successors are reachable from a given terminator instruction.
void SparseSolver::getFeasibleSuccessors(TerminatorInst &TI,
                                         SmallVectorImpl<bool> &Succs,
                                         bool AggressiveUndef) {
  Succs.resize(TI.getNumSuccessors());
  if (TI.getNumSuccessors() == 0) return;

  if (BranchInst *BI = dyn_cast<BranchInst>(&TI)) {
    if (BI->isUnconditional()) {
      Succs[0] = true;
      return;
    }

    LatticeVal BCValue;
    if (AggressiveUndef)
      BCValue = getOrInitValueState(BI->getCondition());
    else
      BCValue = getLatticeState(BI->getCondition());

    if (BCValue == LatticeFunc->getOverdefinedVal() ||
        BCValue == LatticeFunc->getUntrackedVal()) {
      // Overdefined condition variables can branch either way.
      Succs[0] = Succs[1] = true;
      return;
    }

    // If undefined, neither is feasible yet.
    if (BCValue == LatticeFunc->getUndefVal())
      return;

    Constant *C = LatticeFunc->GetConstant(BCValue, BI->getCondition(), *this);
    if (C == 0 || !isa<ConstantInt>(C)) {
      // Non-constant values can go either way.
      Succs[0] = Succs[1] = true;
      return;
    }

    // Constant condition variables mean the branch can only go a single way
    Succs[C->isNullValue()] = true;
    return;
  }

  if (isa<InvokeInst>(TI)) {
    // Invoke instructions successors are always executable.
    // TODO: Could ask the lattice function if the value can throw.
    Succs[0] = Succs[1] = true;
    return;
  }

  if (isa<IndirectBrInst>(TI)) {
    Succs.assign(Succs.size(), true);
    return;
  }

  SwitchInst &SI = cast<SwitchInst>(TI);
  LatticeVal SCValue;
  if (AggressiveUndef)
    SCValue = getOrInitValueState(SI.getCondition());
  else
    SCValue = getLatticeState(SI.getCondition());

  if (SCValue == LatticeFunc->getOverdefinedVal() ||
      SCValue == LatticeFunc->getUntrackedVal()) {
    // All destinations are executable!
    Succs.assign(TI.getNumSuccessors(), true);
    return;
  }

  // If undefined, neither is feasible yet.
  if (SCValue == LatticeFunc->getUndefVal())
    return;

  Constant *C = LatticeFunc->GetConstant(SCValue, SI.getCondition(), *this);
  if (C == 0 || !isa<ConstantInt>(C)) {
    // All destinations are executable!
    Succs.assign(TI.getNumSuccessors(), true);
    return;
  }
  SwitchInst::CaseIt Case = SI.findCaseValue(cast<ConstantInt>(C));
  Succs[Case.getSuccessorIndex()] = true;
}
Ejemplo n.º 26
0
void IA64AsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
  const TargetData *TD = TM.getTargetData();

  if (!GVar->hasInitializer())
    return; // External global require no code

  // Check to see if this is a special global used by LLVM, if so, emit it.
  if (EmitSpecialLLVMGlobal(GVar))
    return;

  O << "\n\n";
  std::string name = Mang->getValueName(GVar);
  Constant *C = GVar->getInitializer();
  unsigned Size = TD->getTypePaddedSize(C->getType());
  unsigned Align = TD->getPreferredAlignmentLog(GVar);

  printVisibility(name, GVar->getVisibility());

  SwitchToSection(TAI->SectionForGlobal(GVar));

  if (C->isNullValue() && !GVar->hasSection()) {
    if (!GVar->isThreadLocal() &&
        (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
      if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.

      if (GVar->hasLocalLinkage()) {
        O << "\t.lcomm " << name << "#," << Size
          << ',' << (1 << Align);
        O << '\n';
      } else {
        O << "\t.common " << name << "#," << Size
          << ',' << (1 << Align);
        O << '\n';
      }

      return;
    }
  }

  switch (GVar->getLinkage()) {
   case GlobalValue::LinkOnceAnyLinkage:
   case GlobalValue::LinkOnceODRLinkage:
   case GlobalValue::CommonLinkage:
   case GlobalValue::WeakAnyLinkage:
   case GlobalValue::WeakODRLinkage:
    // Nonnull linkonce -> weak
    O << "\t.weak " << name << '\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 << TAI->getGlobalDirective() << name << '\n';
    // FALL THROUGH
   case GlobalValue::InternalLinkage:
   case GlobalValue::PrivateLinkage:
    break;
   case GlobalValue::GhostLinkage:
    cerr << "GhostLinkage cannot appear in IA64AsmPrinter!\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!");
  }

  EmitAlignment(Align, GVar);

  if (TAI->hasDotTypeDotSizeDirective()) {
    O << "\t.type " << name << ",@object\n";
    O << "\t.size " << name << ',' << Size << '\n';
  }

  O << name << ":\n";
  EmitGlobalConstant(C);
}
Ejemplo n.º 27
0
bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
                          Module &M, bool isConst, unsigned AddrSpace) const {
  // FIXME: Find better heuristics
  std::stable_sort(Globals.begin(), Globals.end(),
                   [this](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;

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

    // 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.
    GlobalVariable *MergedGV = new GlobalVariable(
        M, MergedTy, isConst, Linkage, MergedInit,
        HasExternal ? "_MergedGlobals_" + TheFirstExternal->getName()
                    : "_MergedGlobals",
        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;
}
Ejemplo n.º 28
0
int VectorField::ReadXML(string xmlfilename)
    {
    FILE *xmlfile;
    mxml_node_t *tree;
    mxml_node_t *node;
    bool bad_attr;

    xmlfile = fopen(xmlfilename.c_str(),"r");
    if (xmlfile == NULL)
       {
       // Failed to open the file.
       cerr << "Error: Unable to open " << xmlfilename << "\n";
       exit(-1);
       }
    tree = mxmlLoadFile(NULL,xmlfile,MXML_NO_CALLBACK);
    fclose(xmlfile);
    if (tree == NULL)
        {
        cerr << "Error: Unable to load the vector field from the file " << xmlfilename << ".\n";
        cerr << "There may be an error in the XML definition of the vector field.\n";
        mxmlDelete(tree);
        exit(-1);
        }

    node = mxmlFindElement(tree,tree,"VectorField",NULL,NULL,MXML_DESCEND);
    if (node == NULL)
        {
        cerr << "Error: No VectorField element found in XML defintion.\n";
        mxmlDelete(tree);
        exit(-1);
        }
    else
        {
        bad_attr = false;
        for (int i = 0; i < node->value.element.num_attrs; ++i)
            {
            string attr = node->value.element.attrs[i].name;
            if (attr != "Name" && attr != "IndependentVariable" && attr != "Description")
                {
                cerr << "Error: The VectorField element has an unknown attribute: " << attr << endl;
                bad_attr = true;
                }
            }
        if (bad_attr)
            exit(-1);
        const char *attr;
        attr = mxmlElementGetAttr(node,"Name");
        if (attr == NULL)
            {
            cerr << "Error: The VectorField element has no Name attribute.\n";
            mxmlDelete(tree);
            exit(-1);
            }
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The VectorField Name \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string s(attr);
            Name(s);
            }
        attr = mxmlElementGetAttr(node,"Description");
        if (attr != NULL)
            {
            string s(attr);
            Description(s);
            }
        attr = mxmlElementGetAttr(node,"IndependentVariable");
        if (attr == NULL)
            IndependentVariable = "t";
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The VectorField IndependentVariable \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string s(attr);
            IndependentVariable = s;
            }
        }

    //
    // Get the constants
    //
    for (node = mxmlFindElement(tree,tree,"Constant",NULL,NULL,MXML_DESCEND);
         node != NULL;
         node = mxmlFindElement(node,tree,"Constant",NULL,NULL,MXML_DESCEND))
        {
        bad_attr = false;
        for (int i = 0; i < node->value.element.num_attrs; ++i)
            {
            string attr = node->value.element.attrs[i].name;
            if (attr != "Name" && attr != "Value" && attr != "Description" && attr != "Latex")
                {
                cerr << "Error: A Constant element has an unknown attribute: " << attr << endl;
                bad_attr = true;
                }
            }
        if (bad_attr)
            {
            cerr << "Valid Constant attributes are: Name, Value, Description, Latex.\n";
            exit(-1);
            } 
        const char *attr;
        attr = mxmlElementGetAttr(node,"Name");
        if (attr == NULL)
            {
            cerr << "Error: A Constant element has no Name attribute.\n";
            mxmlDelete(tree);
            exit(-1);
            }
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The Constant Name \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string name(attr);
            Constant *c = new Constant(name);
            AddConstant(c);
            attr = mxmlElementGetAttr(node,"Description");
            if (attr != NULL)
                {
                string descr(attr);
                c->Description(descr);
                }
            attr = mxmlElementGetAttr(node,"Value");
            if (attr == NULL)
                {
                cerr << "Error: The Constant element with Name=\"" << c->Name() << "\" has no Value attribute.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            else
                {
                string val(attr);
                c->Value(val);
                }
            attr = mxmlElementGetAttr(node,"Latex");
            if (attr != NULL)
                {
                string latex(attr);
                c->Latex(latex);
                }
            }
        }

    //
    // Get the parameters
    //
    for (node = mxmlFindElement(tree,tree,"Parameter",NULL,NULL,MXML_DESCEND);
         node != NULL;
         node = mxmlFindElement(node,tree,"Parameter",NULL,NULL,MXML_DESCEND))
        {
        bad_attr = false;
        for (int i = 0; i < node->value.element.num_attrs; ++i)
            {
            string attr = node->value.element.attrs[i].name;
            if (attr != "Name" && attr != "DefaultValue" && attr != "Description" && attr != "Latex")
                {
                cerr << "Error: A Parameter element has an unknown attribute: " << attr << endl;
                bad_attr = true;
                }
            }
        if (bad_attr)
            {
            cerr << "Valid Parameter attributes are: Name, DefaultValue, Description, Latex.\n";
            exit(-1);
            }
        const char *attr;
        attr = mxmlElementGetAttr(node,"Name");
        if (attr == NULL)
            {
            cerr << "Error: A Parameter element has no Name attribute.\n";
            mxmlDelete(tree);
            exit(-1);
            }
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The Parameter Name \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string name(attr);
            Parameter *p = new Parameter(name);
            AddParameter(p);
            attr = mxmlElementGetAttr(node,"Description");
            if (attr != NULL)
                {
                string descr(attr);
                p->Description(descr);
                }
            attr = mxmlElementGetAttr(node,"DefaultValue");
            if (attr != NULL)
                {
                string defval(attr);
                p->DefaultValue(defval);
                }
            attr = mxmlElementGetAttr(node,"Latex");
            if (attr != NULL)
                {
                string latex(attr);
                p->Latex(latex);
                }
            }
        }

    //
    // Get the auxiliary expressions
    //
    for (node = mxmlFindElement(tree,tree,"Expression",NULL,NULL,MXML_DESCEND);
         node != NULL;
         node = mxmlFindElement(node,tree,"Expression",NULL,NULL,MXML_DESCEND))
        {
        bad_attr = false;
        for (int i = 0; i < node->value.element.num_attrs; ++i)
            {
            string attr = node->value.element.attrs[i].name;
            if (attr != "Name" && attr != "Formula" && attr != "Description" && attr != "Latex")
                {
                cerr << "Error: An Expression element has an unknown attribute: " << attr << endl;
                bad_attr = true;
                }
            }
        if (bad_attr)
            {
            cerr << "Valid Expression attributes are: Name, Formula, Description, Latex.\n";
            exit(-1);
            }
        const char *attr;
        attr = mxmlElementGetAttr(node,"Name");
        if (attr == NULL)
            {
            cerr << "Error: An Expression element has no Name attribute.\n";
            mxmlDelete(tree);
            exit(-1);
            }
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The Expression Name \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string name(attr);
            Expression *e = new Expression(name);
            AddExpression(e);
            attr = mxmlElementGetAttr(node,"Description");
            if (attr != NULL)
                {
                string descr(attr);
                e->Description(descr);
                }
            attr = mxmlElementGetAttr(node,"Formula");
            if (attr == NULL)
                {
                cerr << "Error: The Expression with Name=\"" << e->Name() << "\" has no Formula attribute.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            else
                {
                string f(attr);
                e->Formula(f);
                }
            attr = mxmlElementGetAttr(node,"Latex");
            if (attr != NULL)
                {
                string latex(attr);
                e->Latex(latex);
                }
            }
        }

    //
    // Get the state variables
    //
    for (node = mxmlFindElement(tree,tree,"StateVariable",NULL,NULL,MXML_DESCEND);
         node != NULL;
         node = mxmlFindElement(node,tree,"StateVariable",NULL,NULL,MXML_DESCEND))
        {
        bad_attr = false;
        for (int i = 0; i < node->value.element.num_attrs; ++i)
            {
            string attr = node->value.element.attrs[i].name;
            if (attr != "Name" && attr != "DefaultInitialCondition" && attr != "Description"
                  && attr != "Formula" && attr != "PeriodFrom" && attr != "PeriodTo"
                  && attr != "DefaultHistory" && attr != "Latex")
                {
                cerr << "Error: A StateVariable element has an unknown attribute: " << attr << endl;
                bad_attr = true;
                }
            }
        if (bad_attr)
            {
            cerr << "Valid StateVariable attributes are: Name, Formula, Description, DefaultInitialCondition, DefaultHistory, PeriodFrom, PeriodTo, Latex.\n";
            exit(-1);
            }
        const char *attr;
        attr = mxmlElementGetAttr(node,"Name");
        if (attr == NULL)
            {
            cerr << "Error: A StateVariable element has no Name attribute.\n";
            mxmlDelete(tree);
            exit(-1);
            }
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The StateVariable Name \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string name(attr);
            StateVariable *sv = new StateVariable(name);
            AddStateVariable(sv);
            attr = mxmlElementGetAttr(node,"Description");
            if (attr != NULL)
                {
                string descr(attr);
                sv->Description(descr);
                }
            attr = mxmlElementGetAttr(node,"Formula");
            if (attr == NULL)
                {
                cerr << "Error: The StateVariable with Name=\"" << sv->Name() << "\" has no Formula attribute.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            else
                {
                string f(attr);
                sv->Formula(f);
                }
            attr = mxmlElementGetAttr(node,"PeriodFrom");
            if (attr != NULL)
                {
                string pfrom(attr);
                sv->PeriodicFrom(pfrom);
                }
            attr = mxmlElementGetAttr(node,"PeriodTo");
            if (attr != NULL)
                {
                string pto(attr);
                sv->PeriodicTo(pto);
                }
            if (sv->PeriodicFrom() != "" & sv->PeriodicTo() == "")
                {
                cerr << "Error: The StateVariable with Name=\"" << sv->Name() << "\" has a PeriodicFrom attribute but no PeriodicTo attribute.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            if (sv->PeriodicFrom() == "" & sv->PeriodicTo() != "")
                {
                cerr << "Error: The StateVariable with Name=\"" << sv->Name() << "\" has a PeriodTo attribute but no PeriodicFrom attribute.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            attr = mxmlElementGetAttr(node,"DefaultInitialCondition");
            if (attr != NULL)
                {
                string ic(attr);
                sv->DefaultInitialCondition(ic);
                }
            attr = mxmlElementGetAttr(node,"DefaultHistory");
            if (attr != NULL)
                {
                string hist(attr);
                sv->DefaultHistory(hist);
                }
            attr = mxmlElementGetAttr(node,"Latex");
            if (attr != NULL)
                {
                string latex(attr);
                sv->Latex(latex);
                }
            }
        }

    //
    // Get the functions
    //
    for (node = mxmlFindElement(tree,tree,"Function",NULL,NULL,MXML_DESCEND);
         node != NULL;
         node = mxmlFindElement(node,tree,"Function",NULL,NULL,MXML_DESCEND))
        {
        bad_attr = false;
        for (int i = 0; i < node->value.element.num_attrs; ++i)
            {
            string attr = node->value.element.attrs[i].name;
            if (attr != "Name" && attr != "Formula" && attr != "Description")
                {
                cerr << "Error: A Function element has an unknown attribute: " << attr << endl;
                bad_attr = true;
                }
            }
        if (bad_attr)
            {
            cerr << "Valid Function attributes are: Name, Formula, Description.\n";
            exit(-1);
            }
        const char *attr;
        attr = mxmlElementGetAttr(node,"Name");
        if (attr == NULL)
            {
            cerr << "Error: A Function element has no Name attribute.\n";
            mxmlDelete(tree);
            exit(-1);
            }
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The Function Name \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string name(attr);
            Function *func = new Function(name);
            AddFunction(func);
            attr = mxmlElementGetAttr(node,"Description");
            if (attr != NULL)
                {
                string descr(attr);
                func->Description(descr);
                }
            attr = mxmlElementGetAttr(node,"Formula");
            if (attr == NULL)
                {
                cerr << "Error: The Function element with Name=\"" << func->Name() << "\" has no Formula attibute.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            else
                {
                string f(attr);
                func->Formula(f);
                }
            }
        }


    mxmlDelete(tree);
    return 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 ();
  }



}
Ejemplo n.º 30
0
void ControlFlowIntegrity::ParseAnnotations(void) {
  GlobalVariable *global_ctors = _M.getNamedGlobal("llvm.global.annotations");

  // check for ctor section
  if (!global_ctors || !global_ctors->getOperand(0)) {
    return;
  }

  Constant *c = global_ctors->getInitializer();
  if (!c)
    report_fatal_error("llvm.global.annotations without initializer!", false);

  ConstantArray *CA = dyn_cast<ConstantArray>(c);
  if (!CA)
    report_fatal_error("Cast to ConstantArray failed", true);

  for (Value *Op : ValueOpRange(*CA)) {
    ConstantStruct *CS = dyn_cast<ConstantStruct>(Op);
    if (!CS)
      report_fatal_error("Cast to ConstantStruct failed", true);

    Constant *FP = CS->getOperand(0);
    if (FP->isNullValue())
      break; // found a NULL termintator, stop here

    ConstantExpr *CE;
    Function *F = dyn_cast_or_null<Function>(FP);

    if (F == NULL) {
      // Strip off constant expression cast
      CE = dyn_cast<ConstantExpr>(FP);
      if (!CE)
        report_fatal_error("Cast to ConstantExpr failed", true);
      if (CE->isCast()) {
        FP = CE->getOperand(0);
        F = dyn_cast_or_null<Function>(FP);
      }
    }

    if (!F)
      report_fatal_error("Cast to Function failed", true);

    Constant *SP = CS->getOperand(1);
    if (SP->isNullValue())
      break; // found a NULL termintator, stop here

    // Strip off constant expression cast
    CE = dyn_cast<ConstantExpr>(SP);
    if (!CE)
      report_fatal_error("Cast to ConstantExpr failed", true);
    if (CE->isCast()) {
      SP = CE->getOperand(0);
    }

    Value *V = SP->getOperand(0);
    GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(V);
    if (!GV)
      report_fatal_error("Cast to GlobalVariable failed", false);
    assert(GV && "cast to GlobalVariable failed");

    Constant *cval = GV->getInitializer();
    const StringRef s = (cast<ConstantDataArray>(cval))->getAsCString();
    if (s == ANNOTATION_IGNORE_BLOCK) {
      _IgnoredBlocksFunctions.insert(F->getName());
    }
  }

  if (global_ctors->getNumUses() > 0)
    report_fatal_error("llvm.global.annotations uses count is > 0", false);
}