Ejemplo n.º 1
0
static void SplitUpPHINode(PHINode *Phi) {
  StructType *STy = cast<StructType>(Phi->getType());

  Value *NewStruct = UndefValue::get(STy);
  Instruction *NewStructInsertPt = Phi->getParent()->getFirstInsertionPt();

  // Create a separate PHINode for each struct field.
  for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) {
    SmallVector<unsigned, 1> EVIndexes;
    EVIndexes.push_back(Index);

    PHINode *NewPhi = PHINode::Create(
        STy->getElementType(Index), Phi->getNumIncomingValues(),
        Phi->getName() + ".index", Phi);
    CopyDebug(NewPhi, Phi);
    for (unsigned PhiIndex = 0; PhiIndex < Phi->getNumIncomingValues();
         ++PhiIndex) {
      BasicBlock *IncomingBB = Phi->getIncomingBlock(PhiIndex);
      Value *EV = CopyDebug(
          ExtractValueInst::Create(
              Phi->getIncomingValue(PhiIndex), EVIndexes,
              Phi->getName() + ".extract", IncomingBB->getTerminator()), Phi);
      NewPhi->addIncoming(EV, IncomingBB);
    }

    // Reconstruct the original struct value.
    NewStruct = CopyDebug(
        InsertValueInst::Create(NewStruct, NewPhi, EVIndexes,
                                Phi->getName() + ".insert", NewStructInsertPt),
        Phi);
  }
  Phi->replaceAllUsesWith(NewStruct);
  Phi->eraseFromParent();
}
Ejemplo n.º 2
0
/// \brief Checks if a type could have padding bytes.
bool ArgPromotion::isDenselyPacked(Type *type) {

  // There is no size information, so be conservative.
  if (!type->isSized())
    return false;

  // If the alloc size is not equal to the storage size, then there are padding
  // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
  if (!DL || DL->getTypeSizeInBits(type) != DL->getTypeAllocSizeInBits(type))
    return false;

  if (!isa<CompositeType>(type))
    return true;

  // For homogenous sequential types, check for padding within members.
  if (SequentialType *seqTy = dyn_cast<SequentialType>(type))
    return isa<PointerType>(seqTy) || isDenselyPacked(seqTy->getElementType());

  // Check for padding within and between elements of a struct.
  StructType *StructTy = cast<StructType>(type);
  const StructLayout *Layout = DL->getStructLayout(StructTy);
  uint64_t StartPos = 0;
  for (unsigned i = 0, E = StructTy->getNumElements(); i < E; ++i) {
    Type *ElTy = StructTy->getElementType(i);
    if (!isDenselyPacked(ElTy))
      return false;
    if (StartPos != Layout->getElementOffsetInBits(i))
      return false;
    StartPos += DL->getTypeAllocSizeInBits(ElTy);
  }

  return true;
}
Value *AArch64TTIImpl::getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
                                                         Type *ExpectedType) {
  switch (Inst->getIntrinsicID()) {
  default:
    return nullptr;
  case Intrinsic::aarch64_neon_st2:
  case Intrinsic::aarch64_neon_st3:
  case Intrinsic::aarch64_neon_st4: {
    // Create a struct type
    StructType *ST = dyn_cast<StructType>(ExpectedType);
    if (!ST)
      return nullptr;
    unsigned NumElts = Inst->getNumArgOperands() - 1;
    if (ST->getNumElements() != NumElts)
      return nullptr;
    for (unsigned i = 0, e = NumElts; i != e; ++i) {
      if (Inst->getArgOperand(i)->getType() != ST->getElementType(i))
        return nullptr;
    }
    Value *Res = UndefValue::get(ExpectedType);
    IRBuilder<> Builder(Inst);
    for (unsigned i = 0, e = NumElts; i != e; ++i) {
      Value *L = Inst->getArgOperand(i);
      Res = Builder.CreateInsertValue(Res, L, i);
    }
    return Res;
  }
  case Intrinsic::aarch64_neon_ld2:
  case Intrinsic::aarch64_neon_ld3:
  case Intrinsic::aarch64_neon_ld4:
    if (Inst->getType() == ExpectedType)
      return Inst;
    return nullptr;
  }
}
Ejemplo n.º 4
0
string llvm_type::getTypeName() {
	if (data->isStructTy()) {
		StructType* st = (StructType*) data;
		return st->getName().str();		
	}
	return "";
}
Ejemplo n.º 5
0
  /// Returns the byte alignment of this type
  unsigned getTypeAlignment(const llvm::Type* type)
  {
    using namespace llvm;
    // Array types are aligned to their element type
    if (const ArrayType* psAT = dyn_cast<ArrayType>(type))
    {
      return getTypeAlignment(psAT->getElementType());
    }

    // Struct alignment is the size of its largest contained type
    if (const StructType* structT = dyn_cast<StructType>(type))
    {
      if (structT->isPacked())
        return 1;
      StructType* nonConstTy = const_cast<StructType*>(structT);
      unsigned uAlign = 0, uMaxAlign = 1;
      unsigned uCount = structT->getNumElements();
      for (unsigned i = 0; i < uCount; i++)
      {
          const Type* psElemType = nonConstTy->getTypeAtIndex(i);
          uAlign = getTypeAlignment(psElemType);

          if (uAlign > uMaxAlign)
            uMaxAlign = uAlign;
      }

      return uMaxAlign;
    }

    return getTypeSize(type);
  }
Ejemplo n.º 6
0
static bool SplitUpStore(StoreInst *Store, const DataLayout *DL) {
  StructType *STy = cast<StructType>(Store->getValueOperand()->getType());

  bool NeedsAnotherPass = false;
  // Create a separate store instruction for each struct field.
  for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) {
    SmallVector<Value *, 2> Indexes;
    Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, 0)));
    Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, Index)));
    Value *GEP =
        CopyDebug(GetElementPtrInst::Create(STy,
                      Store->getPointerOperand(), Indexes,
                      Store->getPointerOperand()->getName() + ".index", Store),
                  Store);
    NeedsAnotherPass =
        NeedsAnotherPass || DoAnotherPass(GEP->getType()->getContainedType(0));

    SmallVector<unsigned, 1> EVIndexes;
    EVIndexes.push_back(Index);
    Value *Field = ExtractValueInst::Create(Store->getValueOperand(), EVIndexes,
                                            "", Store);
    StoreInst *NewStore = new StoreInst(Field, GEP, Store);
    ProcessLoadOrStoreAttrs(NewStore, Store, STy, Index, DL);
  }
  Store->eraseFromParent();

  return NeedsAnotherPass;
}
Ejemplo n.º 7
0
static void SplitUpLoad(LoadInst *Load) {
  StructType *STy = cast<StructType>(Load->getType());
  Value *NewStruct = UndefValue::get(STy);

  // Create a separate load instruction for each struct field.
  for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) {
    SmallVector<Value *, 2> Indexes;
    Indexes.push_back(ConstantInt::get(Load->getContext(), APInt(32, 0)));
    Indexes.push_back(ConstantInt::get(Load->getContext(), APInt(32, Index)));
    Value *GEP = CopyDebug(
        GetElementPtrInst::Create(Load->getPointerOperand(), Indexes,
                                  Load->getName() + ".index", Load), Load);
    LoadInst *NewLoad = new LoadInst(GEP, Load->getName() + ".field", Load);
    ProcessLoadOrStoreAttrs(NewLoad, Load);

    // Reconstruct the struct value.
    SmallVector<unsigned, 1> EVIndexes;
    EVIndexes.push_back(Index);
    NewStruct = CopyDebug(
        InsertValueInst::Create(NewStruct, NewLoad, EVIndexes,
                                Load->getName() + ".insert", Load), Load);
  }
  Load->replaceAllUsesWith(NewStruct);
  Load->eraseFromParent();
}
Ejemplo n.º 8
0
void TypeDeduction::Visit(MemberExpression* node)
{
    //TODO: Finish it.
    node->GetContainer()->Accept(this);
    StructType *structType = dynamic_cast<StructType *>(node->GetContainer()->GetTag<Type>("Type"));
    if (structType == NULL)
    {
        
        CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Member expression requires struct type.");        
    }
    
    
    std::vector<Declaration *> * fileds = structType->GetFieldList();
    for (std::vector<Declaration *>::iterator it = fileds->begin(); it != fileds->end(); ++it)
    {
        Declaration *decl = *it;
        if (decl->GetName() == node->GetFieldName())
        {
            Type *fieldType = decl->GetType();
            node->SetTag<Type>("Type", fieldType);
            return;
        }
    }
    
    
    CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "%s is not a member of type %s", node->GetFieldName().c_str(), structType->ToString().c_str());        

    
    abort();
}
Ejemplo n.º 9
0
FunctionType* ArgumentRecovery::createFunctionType(TargetInfo& info, const CallInformation& callInfo, llvm::Module& module, StringRef returnTypeName, SmallVectorImpl<string>& parameterNames)
{
	LLVMContext& ctx = module.getContext();
	Type* integer = Type::getIntNTy(ctx, info.getPointerSize() * CHAR_BIT);
	
	SmallVector<Type*, 8> parameterTypes;
	for (const auto& param : callInfo.parameters())
	{
		if (param.type == ValueInformation::IntegerRegister)
		{
			parameterTypes.push_back(integer);
			parameterNames.push_back(param.registerInfo->name);
		}
		else if (param.type == ValueInformation::Stack)
		{
			parameterTypes.push_back(integer);
			parameterNames.emplace_back();
			raw_string_ostream(parameterNames.back()) << "sp" << param.frameBaseOffset;
		}
		else
		{
			llvm_unreachable("not implemented");
		}
	}
	
	SmallVector<Type*, 2> returnTypes;
	for (const auto& ret : callInfo.returns())
	{
		if (ret.type == ValueInformation::IntegerRegister)
		{
			returnTypes.push_back(integer);
		}
		else
		{
			llvm_unreachable("not implemented");
		}
	}
	
	Type* returnType;
	if (returnTypes.size() == 0)
	{
		returnType = Type::getVoidTy(ctx);
	}
	else if (returnTypes.size() == 1)
	{
		returnType = returnTypes.front();
	}
	else
	{
		StructType* structTy = StructType::create(ctx, returnTypeName);
		structTy->setBody(returnTypes);
		md::setRecoveredReturnFieldNames(module, *structTy, callInfo);
		returnType = structTy;
	}
	
	assert(!callInfo.isVararg() && "not implemented");
	return FunctionType::get(returnType, parameterTypes, false);
}
Ejemplo n.º 10
0
void GcInfo::getGcPointers(StructType *StructTy, const DataLayout &DataLayout,
                           SmallVector<uint32_t, 4> &Pointers) {

  assert(StructTy->isSized());
  const uint32_t PointerSize = DataLayout.getPointerSize();
  const uint32_t TypeSize = DataLayout.getTypeStoreSize(StructTy);

  const StructLayout *MainStructLayout = DataLayout.getStructLayout(StructTy);

  // Walk through the type in pointer-sized jumps.
  for (uint32_t GcOffset = 0; GcOffset < TypeSize; GcOffset += PointerSize) {
    const uint32_t FieldIndex =
        MainStructLayout->getElementContainingOffset(GcOffset);
    Type *FieldTy = StructTy->getStructElementType(FieldIndex);

    // If the field is a value class we need to dive in
    // to its fields and so on, until we reach a primitive type.
    if (FieldTy->isStructTy()) {

      // Prepare to loop through the nesting.
      const StructLayout *OuterStructLayout = MainStructLayout;
      uint32_t OuterOffset = GcOffset;
      uint32_t OuterIndex = FieldIndex;

      while (FieldTy->isStructTy()) {
        // Offset of the Inner class within the outer class
        const uint32_t InnerBaseOffset =
            OuterStructLayout->getElementOffset(OuterIndex);
        // Inner class should start at or before the outer offset
        assert(InnerBaseOffset <= OuterOffset);
        // Determine target offset relative to this inner class.
        const uint32_t InnerOffset = OuterOffset - InnerBaseOffset;
        // Get the inner class layout
        StructType *InnerStructTy = cast<StructType>(FieldTy);
        const StructLayout *InnerStructLayout =
            DataLayout.getStructLayout(InnerStructTy);
        // Find the field at that target offset.
        const uint32_t InnerIndex =
            InnerStructLayout->getElementContainingOffset(InnerOffset);
        // Update for next iteration.
        FieldTy = InnerStructTy->getStructElementType(InnerIndex);
        OuterStructLayout = InnerStructLayout;
        OuterOffset = InnerOffset;
        OuterIndex = InnerIndex;
      }
    }

    if (GcInfo::isGcPointer(FieldTy)) {
      Pointers.push_back(GcOffset);
    }
  }
}
Ejemplo n.º 11
0
void Library::AddStruct(const StructType &structType) {
    if (m_RegisteredStruct.find(structType.GetName()) != m_RegisteredStruct.end()) {
        return;
    }
    m_RegisteredStruct.insert(structType.GetName());
    for (auto it : structType.GetArgs()) {
        std::shared_ptr<StructType> st = it->GetStructType();
        if (st.get() != nullptr) {
            AddStruct(*st);
        }
    }
    structType.EmitForwardDeclaration(m_Stream);
}
Ejemplo n.º 12
0
void ExportPass::ConstructModuleSymbols()
{
  CProcedureType* originalType = dynamic_cast<CProcedureType*>(originalProcedure->get_procedure_symbol()->get_type()) ;
  assert(originalType != NULL) ;

  // The original type takes and returns a struct.  We need to change this
  //  to a list of arguments.

  VoidType* newReturnType = create_void_type(theEnv, IInteger(0), 0) ;
  constructedType = create_c_procedure_type(theEnv,
					    newReturnType,
					    false, // has varargs
					    true, // arguments_known
					    0, // bit alignment
					    LString("ConstructedType")) ;

  StructType* returnType = 
    dynamic_cast<StructType*>(originalType->get_result_type()) ;
  assert(returnType != NULL) ;

  SymbolTable* structSymTab = returnType->get_group_symbol_table() ;
  assert(structSymTab != NULL) ;

  for (int i = 0 ; i < structSymTab->get_symbol_table_object_count() ; ++i)
  {
    VariableSymbol* nextVariable = 
      dynamic_cast<VariableSymbol*>(structSymTab->get_symbol_table_object(i));
    if (nextVariable != NULL)
    {
      // Check to see if this is an output or not
      QualifiedType* cloneType ;
      DataType* cloneBase = 
	dynamic_cast<DataType*>(nextVariable->get_type()->get_base_type()->deep_clone()) ;
      assert(cloneBase != NULL) ;
      cloneType = create_qualified_type(theEnv, cloneBase) ;
 
      if (nextVariable->lookup_annote_by_name("Output") != NULL)
      {
	cloneType->append_annote(create_brick_annote(theEnv, "Output")) ;
	// Why doesn't this stick around?
      }
      constructedType->append_argument(cloneType) ;
    }
  }

  constructedSymbol = create_procedure_symbol(theEnv,
					      constructedType,
					      originalProcedure->get_procedure_symbol()->get_name()) ;
  constructedSymbol->set_definition(NULL) ;

}
Ejemplo n.º 13
0
// Strip any named types of their names.
static void StripTypeNames(Module &M, bool PreserveDbgInfo) {
  std::vector<StructType*> StructTypes;
  M.findUsedStructTypes(StructTypes);

  for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) {
    StructType *STy = StructTypes[i];
    if (STy->isAnonymous() || STy->getName().empty()) continue;
    
    if (PreserveDbgInfo && STy->getName().startswith("llvm.dbg"))
      continue;

    STy->setName("");
  }
}
bool EfficiencySanitizer::instrumentGetElementPtr(Instruction *I, Module &M) {
  GetElementPtrInst *GepInst = dyn_cast<GetElementPtrInst>(I);
  bool Res = false;
  if (GepInst == nullptr || GepInst->getNumIndices() == 1) {
    ++NumIgnoredGEPs;
    return false;
  }
  Type *SourceTy = GepInst->getSourceElementType();
  StructType *StructTy = nullptr;
  ConstantInt *Idx;
  // Check if GEP calculates address from a struct array.
  if (isa<StructType>(SourceTy)) {
    StructTy = cast<StructType>(SourceTy);
    Idx = dyn_cast<ConstantInt>(GepInst->getOperand(1));
    if ((Idx == nullptr || Idx->getSExtValue() != 0) &&
        !shouldIgnoreStructType(StructTy) && StructTyMap.count(StructTy) != 0)
      Res |= insertCounterUpdate(I, StructTy, getArrayCounterIdx(StructTy));
  }
  // Iterate all (except the first and the last) idx within each GEP instruction
  // for possible nested struct field address calculation.
  for (unsigned i = 1; i < GepInst->getNumIndices(); ++i) {
    SmallVector<Value *, 8> IdxVec(GepInst->idx_begin(),
                                   GepInst->idx_begin() + i);
    Type *Ty = GetElementPtrInst::getIndexedType(SourceTy, IdxVec);
    unsigned CounterIdx = 0;
    if (isa<ArrayType>(Ty)) {
      ArrayType *ArrayTy = cast<ArrayType>(Ty);
      StructTy = dyn_cast<StructType>(ArrayTy->getElementType());
      if (shouldIgnoreStructType(StructTy) || StructTyMap.count(StructTy) == 0)
        continue;
      // The last counter for struct array access.
      CounterIdx = getArrayCounterIdx(StructTy);
    } else if (isa<StructType>(Ty)) {
      StructTy = cast<StructType>(Ty);
      if (shouldIgnoreStructType(StructTy) || StructTyMap.count(StructTy) == 0)
        continue;
      // Get the StructTy's subfield index.
      Idx = cast<ConstantInt>(GepInst->getOperand(i+1));
      assert(Idx->getSExtValue() >= 0 &&
             Idx->getSExtValue() < StructTy->getNumElements());
      CounterIdx = getFieldCounterIdx(StructTy) + Idx->getSExtValue();
    }
    Res |= insertCounterUpdate(I, StructTy, CounterIdx);
  }
  if (Res)
    ++NumInstrumentedGEPs;
  else
    ++NumIgnoredGEPs;
  return Res;
}
Ejemplo n.º 15
0
// Strip any named types of their names.
static void StripTypeNames(Module &M, bool PreserveDbgInfo) {
  TypeFinder StructTypes;
  StructTypes.run(M, false);

  for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) {
    StructType *STy = StructTypes[i];
    if (STy->isLiteral() || STy->getName().empty()) continue;
    
    if (PreserveDbgInfo && STy->getName().startswith("llvm.dbg"))
      continue;

    STy->setName("");
  }
}
Ejemplo n.º 16
0
/// Verify - Verify that the specified constraint string is reasonable for the
/// specified function type, and otherwise validate the constraint string.
bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) {
  if (Ty->isVarArg()) return false;
  
  ConstraintInfoVector Constraints = ParseConstraints(ConstStr);
  
  // Error parsing constraints.
  if (Constraints.empty() && !ConstStr.empty()) return false;
  
  unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0;
  unsigned NumIndirect = 0;
  
  for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
    switch (Constraints[i].Type) {
    case InlineAsm::isOutput:
      if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0)
        return false;  // outputs before inputs and clobbers.
      if (!Constraints[i].isIndirect) {
        ++NumOutputs;
        break;
      }
      ++NumIndirect;
      // FALLTHROUGH for Indirect Outputs.
    case InlineAsm::isInput:
      if (NumClobbers) return false;               // inputs before clobbers.
      ++NumInputs;
      break;
    case InlineAsm::isClobber:
      ++NumClobbers;
      break;
    }
  }
  
  switch (NumOutputs) {
  case 0:
    if (!Ty->getReturnType()->isVoidTy()) return false;
    break;
  case 1:
    if (Ty->getReturnType()->isStructTy()) return false;
    break;
  default:
    StructType *STy = dyn_cast<StructType>(Ty->getReturnType());
    if (!STy || STy->getNumElements() != NumOutputs)
      return false;
    break;
  }      
  
  if (Ty->getNumParams() != NumInputs) return false;
  return true;
}
Ejemplo n.º 17
0
// Return LLVM Type if TYPE can be returned as an aggregate, 
// otherwise return NULL.
Type *llvm_mips_aggr_type_for_struct_return(tree type) {
  Type *Ty = ConvertType(type);

  StructType *STy = cast<StructType>(Ty);
  std::vector<Type *> ElementTypes;

  // Special handling for _Complex.
  if (llvm_mips_should_not_return_complex_in_memory(type)) {
    ElementTypes.push_back(Type::getDoubleTy(Context));
    ElementTypes.push_back(Type::getDoubleTy(Context));
    return StructType::get(Context, ElementTypes, STy->isPacked());
  } 

  return NULL;
}
Ejemplo n.º 18
0
static void appendToGlobalArray(const char *Array,
                                Module &M, Function *F, int Priority) {
  IRBuilder<> IRB(M.getContext());
  FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false);

  // Get the current set of static global constructors and add the new ctor
  // to the list.
  SmallVector<Constant *, 16> CurrentCtors;
  StructType *EltTy;
  if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) {
    // If there is a global_ctors array, use the existing struct type, which can
    // have 2 or 3 fields.
    ArrayType *ATy = cast<ArrayType>(GVCtor->getType()->getElementType());
    EltTy = cast<StructType>(ATy->getElementType());
    if (Constant *Init = GVCtor->getInitializer()) {
      unsigned n = Init->getNumOperands();
      CurrentCtors.reserve(n + 1);
      for (unsigned i = 0; i != n; ++i)
        CurrentCtors.push_back(cast<Constant>(Init->getOperand(i)));
    }
    GVCtor->eraseFromParent();
  } else {
    // Use a simple two-field struct if there isn't one already.
    EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy),
                            nullptr);
  }

  // Build a 2 or 3 field global_ctor entry.  We don't take a comdat key.
  Constant *CSVals[3];
  CSVals[0] = IRB.getInt32(Priority);
  CSVals[1] = F;
  // FIXME: Drop support for the two element form in LLVM 4.0.
  if (EltTy->getNumElements() >= 3)
    CSVals[2] = llvm::Constant::getNullValue(IRB.getInt8PtrTy());
  Constant *RuntimeCtorInit =
      ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements()));

  CurrentCtors.push_back(RuntimeCtorInit);

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

  // Create the new global variable and replace all uses of
  // the old global variable with the new one.
  (void)new GlobalVariable(M, NewInit->getType(), false,
                           GlobalValue::AppendingLinkage, NewInit, Array);
}
Ejemplo n.º 19
0
StructTypeDecl* C2Sema::ActOnStructType(const char* name, SourceLocation loc,
            bool isStruct, bool is_public, bool is_global) {
#ifdef SEMA_DEBUG
    std::cerr << COL_SEMA << "SEMA: Struct/Union Type '" << (name ? name : "<anonymous>");
    std::cerr << ANSI_NORMAL << '\n';
#endif
    QualType qt = typeContext.getStructType();
    StructTypeDecl* S = new StructTypeDecl(name, loc, qt, isStruct, is_global, is_public); 
    StructType* ST = cast<StructType>(qt.getTypePtr());
    ST->setDecl(S);
    if (is_global) {
        ast.addType(S);
        addSymbol(S);
    }
    return S;
}
Ejemplo n.º 20
0
void TypeMapTy::linkDefinedTypeBodies() {
  SmallVector<Type *, 16> Elements;
  for (StructType *SrcSTy : SrcDefinitionsToResolve) {
    StructType *DstSTy = cast<StructType>(MappedTypes[SrcSTy]);
    assert(DstSTy->isOpaque());

    // Map the body of the source type over to a new body for the dest type.
    Elements.resize(SrcSTy->getNumElements());
    for (unsigned I = 0, E = Elements.size(); I != E; ++I)
      Elements[I] = get(SrcSTy->getElementType(I));

    DstSTy->setBody(Elements, SrcSTy->isPacked());
    DstStructTypesSet.switchToNonOpaque(DstSTy);
  }
  SrcDefinitionsToResolve.clear();
  DstResolvedOpaqueTypes.clear();
}
Ejemplo n.º 21
0
int main(int argc, char **argv)
{
    InitializeNativeTarget();
    LLVMContext &Context = getGlobalContext();
    Module *m = new Module("test", Context);
    Type *intTy  = Type::getInt64Ty(Context);

    StructType* structTy = StructType::create(Context, "struct.list");
    std::vector<Type*> fields;
    fields.push_back(intTy);
    fields.push_back(PointerType::get(structTy, 0));
    if (structTy->isOpaque()) {
        structTy->setBody(fields, false);
    }

    /*
     * int f1(struct x *p) { return p->next->l1; }
     */
    std::vector<Type*> args_type;
    args_type.push_back(PointerType::get(structTy, 0));

    FunctionType *fnTy = FunctionType::get(intTy, args_type, false);
    Function *func = Function::Create(fnTy,
            GlobalValue::ExternalLinkage, "f1", m);
    Value *v = func->arg_begin();
    BasicBlock *bb = BasicBlock::Create(Context, "EntryBlock", func);
    IRBuilder<> *builder = new IRBuilder<>(bb);
    v = builder->CreateStructGEP(v, 1);
    v = builder->CreateLoad(v, "load0");
    v = builder->CreateStructGEP(v, 0);
    v = builder->CreateLoad(v, "load1");
    builder->CreateRet(v);

    (*m).dump();
    {
        ExecutionEngine *ee = EngineBuilder(m). 
            setEngineKind(EngineKind::JIT).create();
        void *f = ee->getPointerToFunction(func);
        typedef int (*func_t) (struct x *);
        struct x o = {10, NULL}, v = {};
        v.next = &o;
        std::cout << ((func_t)f)(&v) << std::endl;
    }
    return 0;
}
Ejemplo n.º 22
0
StructType *StructType::get(LLVMContext &Context, ArrayRef<Type*> ETypes, 
                            bool isPacked) {
  LLVMContextImpl *pImpl = Context.pImpl;
  AnonStructTypeKeyInfo::KeyTy Key(ETypes, isPacked);
  auto I = pImpl->AnonStructTypes.find_as(Key);
  StructType *ST;

  if (I == pImpl->AnonStructTypes.end()) {
    // Value not found.  Create a new type!
    ST = new (Context.pImpl->TypeAllocator) StructType(Context);
    ST->setSubclassData(SCDB_IsLiteral);  // Literal struct.
    ST->setBody(ETypes, isPacked);
    Context.pImpl->AnonStructTypes.insert(ST);
  } else {
    ST = *I;
  }

  return ST;
}
Ejemplo n.º 23
0
void TypeListItem::CreateChildren(
    wxTreeCtrl* tree, const wxTreeItemId & id) {
  std::vector<StructType*> structTypes;
  module_->findUsedStructTypes(structTypes);
  for (unsigned i = 0, e = structTypes.size(); i != e; ++i) {
    StructType *sty = structTypes[i];
    llvm::StringRef name;

    if (sty->isLiteral()) {
      name = "literal struct";
    } else if (sty->hasName()) {
      name = sty->getName();
    } else {
      continue;
    }
    CreateChild(tree, id,
                new TypeItem(module_, sty, toWxStr(name)));
  }
  tree->SortChildren(id);
}
Ejemplo n.º 24
0
static void SplitUpStore(StoreInst *Store) {
  StructType *STy = cast<StructType>(Store->getValueOperand()->getType());
  // Create a separate store instruction for each struct field.
  for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) {
    SmallVector<Value *, 2> Indexes;
    Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, 0)));
    Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, Index)));
    Value *GEP = CopyDebug(GetElementPtrInst::Create(
                               Store->getPointerOperand(), Indexes,
                               Store->getPointerOperand()->getName() + ".index",
                               Store), Store);
    SmallVector<unsigned, 1> EVIndexes;
    EVIndexes.push_back(Index);
    Value *Field = ExtractValueInst::Create(Store->getValueOperand(),
                                            EVIndexes, "", Store);
    StoreInst *NewStore = new StoreInst(Field, GEP, Store);
    ProcessLoadOrStoreAttrs(NewStore, Store);
  }
  Store->eraseFromParent();
}
Ejemplo n.º 25
0
/// computeTypeMapping - Loop over all of the linked values to compute type
/// mappings.  For example, if we link "extern Foo *x" and "Foo *x = NULL", then
/// we have two struct types 'Foo' but one got renamed when the module was
/// loaded into the same LLVMContext.
void ModuleLinker::computeTypeMapping() {
  // Incorporate globals.
  for (Module::global_iterator I = SrcM->global_begin(),
       E = SrcM->global_end(); I != E; ++I) {
    GlobalValue *DGV = getLinkedToGlobal(I);
    if (DGV == 0) continue;
    
    if (!DGV->hasAppendingLinkage() || !I->hasAppendingLinkage()) {
      TypeMap.addTypeMapping(DGV->getType(), I->getType());
      continue;      
    }
    
    // Unify the element type of appending arrays.
    ArrayType *DAT = cast<ArrayType>(DGV->getType()->getElementType());
    ArrayType *SAT = cast<ArrayType>(I->getType()->getElementType());
    TypeMap.addTypeMapping(DAT->getElementType(), SAT->getElementType());
  }
  
  // Incorporate functions.
  for (Module::iterator I = SrcM->begin(), E = SrcM->end(); I != E; ++I) {
    if (GlobalValue *DGV = getLinkedToGlobal(I))
      TypeMap.addTypeMapping(DGV->getType(), I->getType());
  }

  // Incorporate types by name, scanning all the types in the source module.
  // At this point, the destination module may have a type "%foo = { i32 }" for
  // example.  When the source module got loaded into the same LLVMContext, if
  // it had the same type, it would have been renamed to "%foo.42 = { i32 }".
  // Though it isn't required for correctness, attempt to link these up to clean
  // up the IR.
  std::vector<StructType*> SrcStructTypes;
  SrcM->findUsedStructTypes(SrcStructTypes);
  
  SmallPtrSet<StructType*, 32> SrcStructTypesSet(SrcStructTypes.begin(),
                                                 SrcStructTypes.end());
  
  for (unsigned i = 0, e = SrcStructTypes.size(); i != e; ++i) {
    StructType *ST = SrcStructTypes[i];
    if (!ST->hasName()) continue;
    
    // Check to see if there is a dot in the name followed by a digit.
    size_t DotPos = ST->getName().rfind('.');
    if (DotPos == 0 || DotPos == StringRef::npos ||
        ST->getName().back() == '.' || !isdigit(ST->getName()[DotPos+1]))
      continue;
    
    // Check to see if the destination module has a struct with the prefix name.
    if (StructType *DST = DstM->getTypeByName(ST->getName().substr(0, DotPos)))
      // Don't use it if this actually came from the source module.  They're in
      // the same LLVMContext after all.
      if (!SrcStructTypesSet.count(DST))
        TypeMap.addTypeMapping(DST, ST);
  }

  // Don't bother incorporating aliases, they aren't generally typed well.
  
  // Now that we have discovered all of the type equivalences, get a body for
  // any 'opaque' types in the dest module that are now resolved. 
  TypeMap.linkDefinedTypeBodies();
}
Ejemplo n.º 26
0
void Preparer::expandGlobal(Module &M, GlobalVariable *GV) {
  if (GV->isDeclaration()) return;
  if (GV->getLinkage() == GlobalValue::AppendingLinkage) return;
  Type *OrigType = GV->getType()->getTypeAtIndex((unsigned)0);
  StructType *NewType = StructType::create(GV->getContext(), "pad_global_type");
  NewType->setBody(OrigType, IntegerType::get(GV->getContext(), 8), NULL);

  // FIXME: AddressSpace?
  GlobalVariable *NewGV;
  Constant *NewInit = NULL;
  if (GV->hasInitializer()) {
    assert(GV->getInitializer()->getType() == OrigType);
    NewInit = ConstantStruct::get(NewType, GV->getInitializer(),
        ConstantInt::get(IntegerType::get(GV->getContext(), 8), 0), NULL);
  }
  NewGV = new GlobalVariable(M, NewType, GV->isConstant(), GV->getLinkage(),
      NewInit, "pad_global", GV, GV->isThreadLocal(), 0);

  Constant *NewValue = ConstantExpr::getBitCast(NewGV, GV->getType());
  assert(NewValue->getType() == GV->getType());
  GV->replaceAllUsesWith(NewValue);
}
Ejemplo n.º 27
0
bool PNaClSjLjEH::runOnModule(Module &M) {
  Type *JmpBufTy = ArrayType::get(Type::getInt8Ty(M.getContext()),
                                  kPNaClJmpBufSize);

  // Define "struct ExceptionFrame".
  StructType *ExceptionFrameTy = StructType::create(M.getContext(),
                                                    "ExceptionFrame");
  Type *ExceptionFrameFields[] = {
    JmpBufTy,  // jmp_buf
    ExceptionFrameTy->getPointerTo(),  // struct ExceptionFrame *next
    Type::getInt32Ty(M.getContext())  // Exception info (clause list ID)
  };
  ExceptionFrameTy->setBody(ExceptionFrameFields);

  ExceptionInfoWriter ExcInfoWriter(&M.getContext());
  for (Module::iterator Func = M.begin(), E = M.end(); Func != E; ++Func) {
    FuncRewriter Rewriter(ExceptionFrameTy, &ExcInfoWriter, Func);
    Rewriter.expandFunc();
  }
  ExcInfoWriter.defineGlobalVariables(&M);
  return true;
}
Ejemplo n.º 28
0
static bool SplitUpSelect(SelectInst *Select) {
  StructType *STy = cast<StructType>(Select->getType());
  Value *NewStruct = UndefValue::get(STy);

  bool NeedsAnotherPass = false;
  // Create a separate SelectInst for each struct field.
  for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) {
    SmallVector<unsigned, 1> EVIndexes;
    EVIndexes.push_back(Index);

    Value *TrueVal = CopyDebug(
        ExtractValueInst::Create(Select->getTrueValue(), EVIndexes,
                                 Select->getName() + ".extract", Select),
        Select);
    Value *FalseVal = CopyDebug(
        ExtractValueInst::Create(Select->getFalseValue(), EVIndexes,
                                 Select->getName() + ".extract", Select),
        Select);
    Value *NewSelect =
        CopyDebug(SelectInst::Create(Select->getCondition(), TrueVal, FalseVal,
                                     Select->getName() + ".index", Select),
                  Select);

    NeedsAnotherPass = NeedsAnotherPass || DoAnotherPass(NewSelect);

    // Reconstruct the original struct value.
    NewStruct = CopyDebug(
        InsertValueInst::Create(NewStruct, NewSelect, EVIndexes,
                                Select->getName() + ".insert", Select),
        Select);
  }
  Select->replaceAllUsesWith(NewStruct);
  Select->eraseFromParent();

  return NeedsAnotherPass;
}
Ejemplo n.º 29
0
bool AllocaMerging::areTypesEquivalent(const cheerp::TypeSupport& types, cheerp::PointerAnalyzer& PA, Type* a, Type* b)
{
	//TODO: Integer types may be equivalent as well
	if(a==b)
		return true;
	else if(a->isPointerTy() && b->isPointerTy())
		return true;
	else if(a->isFloatingPointTy() && b->isFloatingPointTy())
		return true;
	else if(a->isArrayTy() && b->isArrayTy())
	{
		return cast<ArrayType>(a)->getNumElements()==cast<ArrayType>(b)->getNumElements() &&
			areTypesEquivalent(types, PA, a->getArrayElementType(), b->getArrayElementType());
	}
	else if(a->isStructTy() && b->isStructTy())
	{
		// TODO: Byte layout structs with the same size are equivalent
		if(cast<StructType>(a)->hasByteLayout() ||
			cast<StructType>(b)->hasByteLayout())
			return false;
		StructType* stA = cast<StructType>(a);
		StructType* stB = cast<StructType>(b);
		if(stA->getNumElements() != stB->getNumElements())
			return false;
		for(uint32_t i=0;i<stA->getNumElements();i++)
		{
			Type* elementA = stA->getElementType(i);
			Type* elementB = stB->getElementType(i);
			// The types needs to have consistent wrapper arrays
			if(types.useWrapperArrayForMember(PA, stA, i) ^ types.useWrapperArrayForMember(PA, stB, i))
				return false;
			if(!areTypesEquivalent(types, PA, elementA, elementB))
				return false;
		}
		return true;
	}
	else
		return false;
}
Ejemplo n.º 30
0
/// cmpType - compares two types,
/// defines total ordering among the types set.
/// See method declaration comments for more details.
int FunctionComparator::cmpType(Type *TyL, Type *TyR) const {

  PointerType *PTyL = dyn_cast<PointerType>(TyL);
  PointerType *PTyR = dyn_cast<PointerType>(TyR);

  if (DL) {
    if (PTyL && PTyL->getAddressSpace() == 0) TyL = DL->getIntPtrType(TyL);
    if (PTyR && PTyR->getAddressSpace() == 0) TyR = DL->getIntPtrType(TyR);
  }

  if (TyL == TyR)
    return 0;

  if (int Res = cmpNumbers(TyL->getTypeID(), TyR->getTypeID()))
    return Res;

  switch (TyL->getTypeID()) {
  default:
    llvm_unreachable("Unknown type!");
    // Fall through in Release mode.
  case Type::IntegerTyID:
  case Type::VectorTyID:
    // TyL == TyR would have returned true earlier.
    return cmpNumbers((uint64_t)TyL, (uint64_t)TyR);

  case Type::VoidTyID:
  case Type::FloatTyID:
  case Type::DoubleTyID:
  case Type::X86_FP80TyID:
  case Type::FP128TyID:
  case Type::PPC_FP128TyID:
  case Type::LabelTyID:
  case Type::MetadataTyID:
    return 0;

  case Type::PointerTyID: {
    assert(PTyL && PTyR && "Both types must be pointers here.");
    return cmpNumbers(PTyL->getAddressSpace(), PTyR->getAddressSpace());
  }

  case Type::StructTyID: {
    StructType *STyL = cast<StructType>(TyL);
    StructType *STyR = cast<StructType>(TyR);
    if (STyL->getNumElements() != STyR->getNumElements())
      return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());

    if (STyL->isPacked() != STyR->isPacked())
      return cmpNumbers(STyL->isPacked(), STyR->isPacked());

    for (unsigned i = 0, e = STyL->getNumElements(); i != e; ++i) {
      if (int Res = cmpType(STyL->getElementType(i),
                            STyR->getElementType(i)))
        return Res;
    }
    return 0;
  }

  case Type::FunctionTyID: {
    FunctionType *FTyL = cast<FunctionType>(TyL);
    FunctionType *FTyR = cast<FunctionType>(TyR);
    if (FTyL->getNumParams() != FTyR->getNumParams())
      return cmpNumbers(FTyL->getNumParams(), FTyR->getNumParams());

    if (FTyL->isVarArg() != FTyR->isVarArg())
      return cmpNumbers(FTyL->isVarArg(), FTyR->isVarArg());

    if (int Res = cmpType(FTyL->getReturnType(), FTyR->getReturnType()))
      return Res;

    for (unsigned i = 0, e = FTyL->getNumParams(); i != e; ++i) {
      if (int Res = cmpType(FTyL->getParamType(i), FTyR->getParamType(i)))
        return Res;
    }
    return 0;
  }

  case Type::ArrayTyID: {
    ArrayType *ATyL = cast<ArrayType>(TyL);
    ArrayType *ATyR = cast<ArrayType>(TyR);
    if (ATyL->getNumElements() != ATyR->getNumElements())
      return cmpNumbers(ATyL->getNumElements(), ATyR->getNumElements());
    return cmpType(ATyL->getElementType(), ATyR->getElementType());
  }
  }
}