X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FTransformInternals.cpp;h=8cd2511e7c5f1465f5f4059bf9f9ff956d620882;hb=dac58ad983c62b49629e1f2969f4e0a621167d63;hp=ac8181b72241cee3cc4e1890749ace0e3dbb2a5e;hpb=c0b90e7dd575ba59035334397722d677231a8f13;p=oota-llvm.git diff --git a/lib/Transforms/TransformInternals.cpp b/lib/Transforms/TransformInternals.cpp index ac8181b7224..8cd2511e7c5 100644 --- a/lib/Transforms/TransformInternals.cpp +++ b/lib/Transforms/TransformInternals.cpp @@ -1,4 +1,11 @@ -//===-- TransformInternals.cpp - Implement shared functions for transforms --=// +//===- TransformInternals.cpp - Implement shared functions for transforms -===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file defines shared functions used by the different components of the // Transforms library. @@ -6,85 +13,30 @@ //===----------------------------------------------------------------------===// #include "TransformInternals.h" -#include "llvm/Method.h" #include "llvm/Type.h" -#include "llvm/ConstPoolVals.h" - -// TargetData Hack: Eventually we will have annotations given to us by the -// backend so that we know stuff about type size and alignments. For now -// though, just use this, because it happens to match the model that GCC uses. -// -const TargetData TD("LevelRaise: Should be GCC though!"); - -// losslessCastableTypes - Return true if the types are bitwise equivalent. -// This predicate returns true if it is possible to cast from one type to -// another without gaining or losing precision, or altering the bits in any way. -// -bool losslessCastableTypes(const Type *T1, const Type *T2) { - if (!T1->isPrimitiveType() && !T1->isPointerType()) return false; - if (!T2->isPrimitiveType() && !T2->isPointerType()) return false; - - if (T1->getPrimitiveID() == T2->getPrimitiveID()) - return true; // Handles identity cast, and cast of differing pointer types - - // Now we know that they are two differing primitive or pointer types - switch (T1->getPrimitiveID()) { - case Type::UByteTyID: return T2 == Type::SByteTy; - case Type::SByteTyID: return T2 == Type::UByteTy; - case Type::UShortTyID: return T2 == Type::ShortTy; - case Type::ShortTyID: return T2 == Type::UShortTy; - case Type::UIntTyID: return T2 == Type::IntTy; - case Type::IntTyID: return T2 == Type::UIntTy; - case Type::ULongTyID: - case Type::LongTyID: - case Type::PointerTyID: - return T2 == Type::ULongTy || T2 == Type::LongTy || - T2->getPrimitiveID() == Type::PointerTyID; - default: - return false; // Other types have no identity values - } -} - - -// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI) -// with a value, then remove and delete the original instruction. -// -void ReplaceInstWithValue(BasicBlock::InstListType &BIL, - BasicBlock::iterator &BI, Value *V) { - Instruction *I = *BI; - // Replaces all of the uses of the instruction with uses of the value - I->replaceAllUsesWith(V); - - // Remove the unneccesary instruction now... - BIL.remove(BI); - - // Make sure to propogate a name if there is one already... - if (I->hasName() && !V->hasName()) - V->setName(I->getName(), BIL.getParent()->getSymbolTable()); - - // Remove the dead instruction now... - delete I; -} - - -// ReplaceInstWithInst - Replace the instruction specified by BI with the -// instruction specified by I. The original instruction is deleted and BI is -// updated to point to the new instruction. -// -void ReplaceInstWithInst(BasicBlock::InstListType &BIL, - BasicBlock::iterator &BI, Instruction *I) { - assert(I->getParent() == 0 && - "ReplaceInstWithInst: Instruction already inserted into basic block!"); +#include "llvm/Function.h" +#include "llvm/Instructions.h" +using namespace llvm; + +static const Type *getStructOffsetStep(const StructType *STy, uint64_t &Offset, + std::vector &Indices, + const TargetData &TD) { + assert(Offset < TD.getTypeSize(STy) && "Offset not in composite!"); + const StructLayout *SL = TD.getStructLayout(STy); - // Insert the new instruction into the basic block... - BI = BIL.insert(BI, I)+1; + // This loop terminates always on a 0 <= i < MemberOffsets.size() + unsigned i; + for (i = 0; i < SL->MemberOffsets.size()-1; ++i) + if (Offset >= SL->MemberOffsets[i] && Offset < SL->MemberOffsets[i+1]) + break; - // Replace all uses of the old instruction, and delete it. - ReplaceInstWithValue(BIL, BI, I); + assert(Offset >= SL->MemberOffsets[i] && + (i == SL->MemberOffsets.size()-1 || Offset < SL->MemberOffsets[i+1])); - // Reexamine the instruction just inserted next time around the cleanup pass - // loop. - --BI; + // Make sure to save the current index... + Indices.push_back(ConstantUInt::get(Type::UIntTy, i)); + Offset = SL->MemberOffsets[i]; + return STy->getContainedType(i); } @@ -99,33 +51,41 @@ void ReplaceInstWithInst(BasicBlock::InstListType &BIL, // case, this routine will not drill down to the leaf type. Set StopEarly to // false if you want a leaf // -const Type *getStructOffsetType(const Type *Ty, unsigned &Offset, - vector &Offsets, - bool StopEarly = true) { - if (!isa(Ty) || (Offset == 0 && StopEarly)) { - Offset = 0; // Return the offset that we were able to acheive +const Type *llvm::getStructOffsetType(const Type *Ty, unsigned &Offset, + std::vector &Indices, + const TargetData &TD, bool StopEarly) { + if (Offset == 0 && StopEarly && !Indices.empty()) return Ty; // Return the leaf type - } - - assert(Offset < TD.getTypeSize(Ty) && "Offset not in struct!"); - const StructType *STy = cast(Ty); - const StructLayout *SL = TD.getStructLayout(STy); - - // This loop terminates always on a 0 <= i < MemberOffsets.size() - unsigned i; - for (i = 0; i < SL->MemberOffsets.size()-1; ++i) - if (Offset >= SL->MemberOffsets[i] && Offset < SL->MemberOffsets[i+1]) - break; - - assert(Offset >= SL->MemberOffsets[i] && - (i == SL->MemberOffsets.size()-1 || Offset < SL->MemberOffsets[i+1])); - // Make sure to save the current index... - Offsets.push_back(ConstPoolUInt::get(Type::UByteTy, i)); + uint64_t ThisOffset; + const Type *NextType; + if (const StructType *STy = dyn_cast(Ty)) { + if (STy->getNumElements()) { + Offset = 0; + return STy; + } + + ThisOffset = Offset; + NextType = getStructOffsetStep(STy, ThisOffset, Indices, TD); + } else if (const ArrayType *ATy = dyn_cast(Ty)) { + assert(Offset == 0 || Offset < TD.getTypeSize(ATy) && + "Offset not in composite!"); + + NextType = ATy->getElementType(); + unsigned ChildSize = (unsigned)TD.getTypeSize(NextType); + if (ConstantSInt::isValueValidForType(Type::IntTy, Offset/ChildSize)) + Indices.push_back(ConstantSInt::get(Type::IntTy, Offset/ChildSize)); + else + Indices.push_back(ConstantSInt::get(Type::LongTy, Offset/ChildSize)); + ThisOffset = (Offset/ChildSize)*ChildSize; + } else { + Offset = 0; // Return the offset that we were able to achieve + return Ty; // Return the leaf type + } - unsigned SubOffs = Offset - SL->MemberOffsets[i]; - const Type *LeafTy = getStructOffsetType(STy->getElementTypes()[i], SubOffs, - Offsets); - Offset = SL->MemberOffsets[i] + SubOffs; + unsigned SubOffs = unsigned(Offset - ThisOffset); + const Type *LeafTy = getStructOffsetType(NextType, SubOffs, + Indices, TD, StopEarly); + Offset = unsigned(ThisOffset + SubOffs); return LeafTy; }