blob: 4eb3792f0f3660f2c7fafe895d922f885607c83c [file] [log] [blame]
//===- SCUtils.h - Utility Functions for SAFECode ----------------------------//
//
// The SAFECode Compiler
//
// 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 implements several utility functions used by SAFECode.
//
//===----------------------------------------------------------------------===//
#ifndef _SCUTILS_H_
#define _SCUTILS_H_
#include "llvm/BasicBlock.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/LLVMContext.h"
#include <vector>
#include <set>
#include <string>
using namespace llvm;
namespace llvm {
//
// Function: isCheckingCall()
//
// Description:
// Determine whether a function is a checking routine inserted by SafeCode.
//
// FIXME: currently the function stays in CodeDuplication.cpp, it
// should be a separate cpp file.
bool isCheckingCall(const std::string & functionName);
//
// Function: getVoidPtrType()
//
// Description:
// Return a pointer to the LLVM type for a void pointer.
//
// Return value:
// A pointer to an LLVM type for the void pointer.
//
// Notes:
// This function cannot be used in a multi-threaded program because it uses
// the LLVM Global Context.
//
// Many, many passes create an LLVM void pointer type, and the code for it
// takes up most of the 80 columns available in a line. This function should
// be easily inlined by the compiler and ease readability of the code (as well
// as centralize changes when LLVM's Type API is changed).
//
static inline
PointerType * getVoidPtrType(void) {
const Type * Int8Type = IntegerType::getInt8Ty(getGlobalContext());
return PointerType::getUnqual(Int8Type);
}
//
// Function: castTo()
//
// Description:
// Given an LLVM value, insert a cast instruction to make it a given type.
//
static inline Value *
castTo (Value * V, const Type * Ty, Twine Name, Instruction * InsertPt) {
//
// Don't bother creating a cast if it's already the correct type.
//
assert (V && "castTo: trying to cast a NULL Value!\n");
if (V->getType() == Ty)
return V;
//
// If it's a constant, just create a constant expression.
//
if (Constant * C = dyn_cast<Constant>(V)) {
Constant * CE = ConstantExpr::getZExtOrBitCast (C, Ty);
return CE;
}
//
// Otherwise, insert a cast instruction.
//
return CastInst::CreateZExtOrBitCast (V, Ty, Name, InsertPt);
}
static inline Instruction *
castTo (Instruction * I, const Type * Ty, Twine Name, Instruction * InsertPt) {
//
// Don't bother creating a cast if it's already the correct type.
//
assert (I && "castTo: trying to cast a NULL Instruction!\n");
if (I->getType() == Ty)
return I;
//
// Otherwise, insert a cast instruction.
//
return CastInst::CreateZExtOrBitCast (I, Ty, Name, InsertPt);
}
static inline Value *
castTo (Value * V, const Type * Ty, Instruction * InsertPt) {
return castTo (V, Ty, "casted", InsertPt);
}
//
// Function: indexesStructsOnly()
//
// Description:
// Determines whether the given GEP expression only indexes into structures.
//
// Return value:
// true - This GEP only indexes into structures.
// false - This GEP indexes into one or more arrays.
//
static inline bool
indexesStructsOnly (GetElementPtrInst * GEP) {
const Type * PType = GEP->getPointerOperand()->getType();
const Type * ElementType;
unsigned int index = 1;
std::vector<Value *> Indices;
unsigned int maxOperands = GEP->getNumOperands() - 1;
//
// Check the first index of the GEP. If it is non-zero, then it doesn't
// matter what type we're indexing into; we're indexing into an array.
//
if (ConstantInt * CI = dyn_cast<ConstantInt>(GEP->getOperand(1)))
if (!(CI->isNullValue ()))
return false;
//
// Scan through all types except for the last. If any of them are an array
// type, the GEP is indexing into an array.
//
// If the last type is an array, the GEP returns a pointer to an array. That
// means the GEP itself is not indexing into the array; this is why we don't
// check the type of the last GEP operand.
//
for (index = 1; index < maxOperands; ++index) {
Indices.push_back (GEP->getOperand(index));
ElementType = GetElementPtrInst::getIndexedType (PType,
Indices.begin(),
Indices.end());
assert (ElementType && "ElementType is NULL!");
if (isa<ArrayType>(ElementType)) {
return false;
}
}
return true;
}
//
// Function: peelCasts()
//
// Description:
// This method peels off casts to get to the original instruction that
// generated the value for the given instruction.
//
// Inputs:
// PointerOperand - The value off of which we will peel the casts.
//
// Outputs:
// Chain - The set of values that are between the original value and the
// specified value.
//
// Return value:
// A pointer to the LLVM value that originates the specified LLVM value.
//
static inline Value *
peelCasts (Value * PointerOperand, std::set<Value *> & Chain) {
Value * SourcePointer = PointerOperand;
bool done = false;
while (!done) {
//
// Trace through constant cast and GEP expressions
//
if (ConstantExpr * cExpr = dyn_cast<ConstantExpr>(SourcePointer)) {
if (cExpr->isCast()) {
if (isa<PointerType>(cExpr->getOperand(0)->getType())) {
Chain.insert (SourcePointer);
SourcePointer = cExpr->getOperand(0);
continue;
}
}
// We cannot handle this expression; break out of the loop
break;
}
//
// Trace back through cast instructions.
//
if (CastInst * CastI = dyn_cast<CastInst>(SourcePointer)) {
if (isa<PointerType>(CastI->getOperand(0)->getType())) {
Chain.insert (SourcePointer);
SourcePointer = CastI->getOperand(0);
continue;
}
break;
}
// We can't scan through any more instructions; give up
done = true;
}
return SourcePointer;
}
}
#endif