#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
+#include "llvm/GlobalVariable.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
Value *BuildSubAggregate(Value *From, Value* To, const Type *IndexedType,
SmallVector<unsigned, 10> &Idxs,
unsigned IdxSkip,
- Instruction &InsertBefore) {
+ Instruction *InsertBefore) {
const llvm::StructType *STy = llvm::dyn_cast<llvm::StructType>(IndexedType);
if (STy) {
+ // Save the original To argument so we can modify it
+ Value *OrigTo = To;
// General case, the type indexed by Idxs is a struct
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
// Process each struct element recursively
Idxs.push_back(i);
+ Value *PrevTo = To;
To = BuildSubAggregate(From, To, STy->getElementType(i), Idxs, IdxSkip,
InsertBefore);
Idxs.pop_back();
+ if (!To) {
+ // Couldn't find any inserted value for this index? Cleanup
+ while (PrevTo != OrigTo) {
+ InsertValueInst* Del = cast<InsertValueInst>(PrevTo);
+ PrevTo = Del->getAggregateOperand();
+ Del->eraseFromParent();
+ }
+ // Stop processing elements
+ break;
+ }
}
- return To;
- } else {
- // Base case, the type indexed by SourceIdxs is not a struct
- // Load the value from the nested struct into the sub struct (and skip
- // IdxSkip indices when indexing the sub struct).
- Instruction *V = llvm::ExtractValueInst::Create(From, Idxs.begin(),
- Idxs.end(), "tmp",
- &InsertBefore);
- Instruction *Ins = llvm::InsertValueInst::Create(To, V,
- Idxs.begin() + IdxSkip,
- Idxs.end(), "tmp",
- &InsertBefore);
- return Ins;
+ // If we succesfully found a value for each of our subaggregates
+ if (To)
+ return To;
}
+ // Base case, the type indexed by SourceIdxs is not a struct, or not all of
+ // the struct's elements had a value that was inserted directly. In the latter
+ // case, perhaps we can't determine each of the subelements individually, but
+ // we might be able to find the complete struct somewhere.
+
+ // Find the value that is at that particular spot
+ Value *V = FindInsertedValue(From, Idxs.begin(), Idxs.end());
+
+ if (!V)
+ return NULL;
+
+ // Insert the value in the new (sub) aggregrate
+ return llvm::InsertValueInst::Create(To, V, Idxs.begin() + IdxSkip,
+ Idxs.end(), "tmp", InsertBefore);
}
// This helper takes a nested struct and extracts a part of it (which is again a
// and the indices "1, 1" this returns
// { c, d }.
//
-// It does this by inserting an extractvalue and insertvalue for each element in
-// the resulting struct, as opposed to just inserting a single struct. This
-// allows for later folding of these individual extractvalue instructions with
-// insertvalue instructions that fill the nested struct.
+// It does this by inserting an insertvalue for each element in the resulting
+// struct, as opposed to just inserting a single struct. This will only work if
+// each of the elements of the substruct are known (ie, inserted into From by an
+// insertvalue instruction somewhere).
//
-// Any inserted instructions are inserted before InsertBefore
+// All inserted insertvalue instructions are inserted before InsertBefore
Value *BuildSubAggregate(Value *From, const unsigned *idx_begin,
- const unsigned *idx_end, Instruction &InsertBefore) {
+ const unsigned *idx_end, Instruction *InsertBefore) {
+ assert(InsertBefore && "Must have someplace to insert!");
const Type *IndexedType = ExtractValueInst::getIndexedType(From->getType(),
idx_begin,
idx_end);
/// FindInsertedValue - Given an aggregrate and an sequence of indices, see if
/// the scalar value indexed is already around as a register, for example if it
/// were inserted directly into the aggregrate.
+///
+/// If InsertBefore is not null, this function will duplicate (modified)
+/// insertvalues when a part of a nested struct is extracted.
Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin,
- const unsigned *idx_end, Instruction &InsertBefore) {
+ const unsigned *idx_end, Instruction *InsertBefore) {
// Nothing to index? Just return V then (this is useful at the end of our
// recursion)
if (idx_begin == idx_end)
const unsigned *req_idx = idx_begin;
for (const unsigned *i = I->idx_begin(), *e = I->idx_end();
i != e; ++i, ++req_idx) {
- if (req_idx == idx_end)
- // The requested index is a part of a nested aggregate. Handle this
- // specially.
- return BuildSubAggregate(V, idx_begin, req_idx, InsertBefore);
+ if (req_idx == idx_end) {
+ if (InsertBefore)
+ // The requested index identifies a part of a nested aggregate. Handle
+ // this specially. For example,
+ // %A = insertvalue { i32, {i32, i32 } } undef, i32 10, 1, 0
+ // %B = insertvalue { i32, {i32, i32 } } %A, i32 11, 1, 1
+ // %C = extractvalue {i32, { i32, i32 } } %B, 1
+ // This can be changed into
+ // %A = insertvalue {i32, i32 } undef, i32 10, 0
+ // %C = insertvalue {i32, i32 } %A, i32 11, 1
+ // which allows the unused 0,0 element from the nested struct to be
+ // removed.
+ return BuildSubAggregate(V, idx_begin, req_idx, InsertBefore);
+ else
+ // We can't handle this without inserting insertvalues
+ return 0;
+ }
// This insert value inserts something else than what we are looking for.
// See if the (aggregrate) value inserted into has the value we are
// Calculate the number of indices required
unsigned size = I->getNumIndices() + (idx_end - idx_begin);
// Allocate some space to put the new indices in
- unsigned *new_begin = new unsigned[size];
- // Auto cleanup this array
- std::auto_ptr<unsigned> newptr(new_begin);
- // Start inserting at the beginning
- unsigned *new_end = new_begin;
+ SmallVector<unsigned, 5> Idxs;
+ Idxs.reserve(size);
// Add indices from the extract value instruction
for (const unsigned *i = I->idx_begin(), *e = I->idx_end();
- i != e; ++i, ++new_end)
- *new_end = *i;
+ i != e; ++i)
+ Idxs.push_back(*i);
// Add requested indices
- for (const unsigned *i = idx_begin, *e = idx_end; i != e; ++i, ++new_end)
- *new_end = *i;
+ for (const unsigned *i = idx_begin, *e = idx_end; i != e; ++i)
+ Idxs.push_back(*i);
- assert((unsigned)(new_end - new_begin) == size
+ assert(Idxs.size() == size
&& "Number of indices added not correct?");
- return FindInsertedValue(I->getAggregateOperand(), new_begin, new_end,
+ return FindInsertedValue(I->getAggregateOperand(), Idxs.begin(), Idxs.end(),
InsertBefore);
}
// Otherwise, we don't know (such as, extracting from a function return value
// or load instruction)
return 0;
}
+
+/// GetConstantStringInfo - This function computes the length of a
+/// null-terminated C string pointed to by V. If successful, it returns true
+/// and returns the string in Str. If unsuccessful, it returns false.
+bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset,
+ bool StopAtNul) {
+ // If V is NULL then return false;
+ if (V == NULL) return false;
+
+ // Look through bitcast instructions.
+ if (BitCastInst *BCI = dyn_cast<BitCastInst>(V))
+ return GetConstantStringInfo(BCI->getOperand(0), Str, Offset, StopAtNul);
+
+ // If the value is not a GEP instruction nor a constant expression with a
+ // GEP instruction, then return false because ConstantArray can't occur
+ // any other way
+ User *GEP = 0;
+ if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
+ GEP = GEPI;
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
+ if (CE->getOpcode() == Instruction::BitCast)
+ return GetConstantStringInfo(CE->getOperand(0), Str, Offset, StopAtNul);
+ if (CE->getOpcode() != Instruction::GetElementPtr)
+ return false;
+ GEP = CE;
+ }
+
+ if (GEP) {
+ // Make sure the GEP has exactly three arguments.
+ if (GEP->getNumOperands() != 3)
+ return false;
+
+ // Make sure the index-ee is a pointer to array of i8.
+ const PointerType *PT = cast<PointerType>(GEP->getOperand(0)->getType());
+ const ArrayType *AT = dyn_cast<ArrayType>(PT->getElementType());
+ if (AT == 0 || AT->getElementType() != Type::Int8Ty)
+ return false;
+
+ // Check to make sure that the first operand of the GEP is an integer and
+ // has value 0 so that we are sure we're indexing into the initializer.
+ ConstantInt *FirstIdx = dyn_cast<ConstantInt>(GEP->getOperand(1));
+ if (FirstIdx == 0 || !FirstIdx->isZero())
+ return false;
+
+ // If the second index isn't a ConstantInt, then this is a variable index
+ // into the array. If this occurs, we can't say anything meaningful about
+ // the string.
+ uint64_t StartIdx = 0;
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
+ StartIdx = CI->getZExtValue();
+ else
+ return false;
+ return GetConstantStringInfo(GEP->getOperand(0), Str, StartIdx+Offset,
+ StopAtNul);
+ }
+
+ // The GEP instruction, constant or instruction, must reference a global
+ // variable that is a constant and is initialized. The referenced constant
+ // initializer is the array that we'll use for optimization.
+ GlobalVariable* GV = dyn_cast<GlobalVariable>(V);
+ if (!GV || !GV->isConstant() || !GV->hasInitializer())
+ return false;
+ Constant *GlobalInit = GV->getInitializer();
+
+ // Handle the ConstantAggregateZero case
+ if (isa<ConstantAggregateZero>(GlobalInit)) {
+ // This is a degenerate case. The initializer is constant zero so the
+ // length of the string must be zero.
+ Str.clear();
+ return true;
+ }
+
+ // Must be a Constant Array
+ ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
+ if (Array == 0 || Array->getType()->getElementType() != Type::Int8Ty)
+ return false;
+
+ // Get the number of elements in the array
+ uint64_t NumElts = Array->getType()->getNumElements();
+
+ if (Offset > NumElts)
+ return false;
+
+ // Traverse the constant array from 'Offset' which is the place the GEP refers
+ // to in the array.
+ Str.reserve(NumElts-Offset);
+ for (unsigned i = Offset; i != NumElts; ++i) {
+ Constant *Elt = Array->getOperand(i);
+ ConstantInt *CI = dyn_cast<ConstantInt>(Elt);
+ if (!CI) // This array isn't suitable, non-int initializer.
+ return false;
+ if (StopAtNul && CI->isZero())
+ return true; // we found end of string, success!
+ Str += (char)CI->getZExtValue();
+ }
+
+ // The array isn't null terminated, but maybe this is a memcpy, not a strcpy.
+ return true;
+}