Ejemplo n.º 1
0
/// ComputeValueVTs - Given an LLVM IR type, compute a sequence of
/// EVTs that represent all the individual underlying
/// non-aggregate types that comprise it.
///
/// If Offsets is non-null, it points to a vector to be filled in
/// with the in-memory offsets of each of the individual values.
///
void llvm::ComputeValueVTs(const TargetLowering &TLI, Type *Ty,
                           SmallVectorImpl<EVT> &ValueVTs,
                           SmallVectorImpl<uint64_t> *Offsets,
                           uint64_t StartingOffset) {
  // Given a struct type, recursively traverse the elements.
  if (StructType *STy = dyn_cast<StructType>(Ty)) {
    const StructLayout *SL = TLI.getDataLayout()->getStructLayout(STy);
    for (StructType::element_iterator EB = STy->element_begin(),
                                      EI = EB,
                                      EE = STy->element_end();
         EI != EE; ++EI)
      ComputeValueVTs(TLI, *EI, ValueVTs, Offsets,
                      StartingOffset + SL->getElementOffset(EI - EB));
    return;
  }
  // Given an array type, recursively traverse the elements.
  if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
    Type *EltTy = ATy->getElementType();
    uint64_t EltSize = TLI.getDataLayout()->getTypeAllocSize(EltTy);
    for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
      ComputeValueVTs(TLI, EltTy, ValueVTs, Offsets,
                      StartingOffset + i * EltSize);
    return;
  }
  // Interpret void as zero return values.
  if (Ty->isVoidTy())
    return;
  // Base case: we can get an EVT for this LLVM IR type.
  ValueVTs.push_back(TLI.getValueType(Ty));
  if (Offsets)
    Offsets->push_back(StartingOffset);
}
Ejemplo n.º 2
0
/// OptimizeNoopCopyExpression - If the specified cast instruction is a noop
/// copy (e.g. it's casting from one pointer type to another, i32->i8 on PPC),
/// sink it into user blocks to reduce the number of virtual
/// registers that must be created and coalesced.
///
/// Return true if any changes are made.
///
static bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI) {
    // If this is a noop copy,
    EVT SrcVT = TLI.getValueType(CI->getOperand(0)->getType());
    EVT DstVT = TLI.getValueType(CI->getType());

    // This is an fp<->int conversion?
    if (SrcVT.isInteger() != DstVT.isInteger())
        return false;

    // If this is an extension, it will be a zero or sign extension, which
    // isn't a noop.
    if (SrcVT.bitsLT(DstVT)) return false;

    // If these values will be promoted, find out what they will be promoted
    // to.  This helps us consider truncates on PPC as noop copies when they
    // are.
    if (TLI.getTypeAction(CI->getContext(), SrcVT) ==
            TargetLowering::TypePromoteInteger)
        SrcVT = TLI.getTypeToTransformTo(CI->getContext(), SrcVT);
    if (TLI.getTypeAction(CI->getContext(), DstVT) ==
            TargetLowering::TypePromoteInteger)
        DstVT = TLI.getTypeToTransformTo(CI->getContext(), DstVT);

    // If, after promotion, these are the same types, this is a noop copy.
    if (SrcVT != DstVT)
        return false;

    BasicBlock *DefBB = CI->getParent();

    /// InsertedCasts - Only insert a cast in each block once.
    DenseMap<BasicBlock*, CastInst*> InsertedCasts;

    bool MadeChange = false;
    for (Value::use_iterator UI = CI->use_begin(), E = CI->use_end();
            UI != E; ) {
        Use &TheUse = UI.getUse();
        Instruction *User = cast<Instruction>(*UI);

        // Figure out which BB this cast is used in.  For PHI's this is the
        // appropriate predecessor block.
        BasicBlock *UserBB = User->getParent();
        if (PHINode *PN = dyn_cast<PHINode>(User)) {
            UserBB = PN->getIncomingBlock(UI);
        }

        // Preincrement use iterator so we don't invalidate it.
        ++UI;

        // If this user is in the same block as the cast, don't change the cast.
        if (UserBB == DefBB) continue;

        // If we have already inserted a cast into this block, use it.
        CastInst *&InsertedCast = InsertedCasts[UserBB];

        if (!InsertedCast) {
            BasicBlock::iterator InsertPt = UserBB->getFirstInsertionPt();
            InsertedCast =
                CastInst::Create(CI->getOpcode(), CI->getOperand(0), CI->getType(), "",
                                 InsertPt);
            MadeChange = true;
        }

        // Replace a use of the cast with a use of the new cast.
        TheUse = InsertedCast;
        ++NumCastUses;
    }

    // If we removed all uses, nuke the cast.
    if (CI->use_empty()) {
        CI->eraseFromParent();
        MadeChange = true;
    }

    return MadeChange;
}