Newer
Older
//===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Constants.h"
#include "llvm/Analysis/ValueTracking.h"
Jim Laskey
committed
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineFunction.h"
Evan Cheng
committed
#include "llvm/CodeGen/Passes.h"
Jim Laskey
committed
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Intrinsics.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Streams.h"
using namespace llvm::dwarf;
// Handle the Pass registration stuff necessary to use TargetData's.
static RegisterPass<MachineModuleInfo>
X("machinemoduleinfo", "Module Information");
//===----------------------------------------------------------------------===//
/// getGlobalVariablesUsing - Return all of the GlobalVariables which have the
/// specified value in their initializer somewhere.
static void
getGlobalVariablesUsing(Value *V, std::vector<GlobalVariable*> &Result) {
// Scan though value users.
for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I)) {
// If the user is a GlobalVariable then add to result.
Result.push_back(GV);
} else if (Constant *C = dyn_cast<Constant>(*I)) {
// If the user is a constant variable then scan its users
getGlobalVariablesUsing(C, Result);
}
}
}
/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
/// named GlobalVariable.
Bill Wendling
committed
static void
getGlobalVariablesUsing(Module &M, const std::string &RootName,
std::vector<GlobalVariable*> &Result) {
Jim Laskey
committed
std::vector<const Type*> FieldTypes;
FieldTypes.push_back(Type::Int32Ty);
FieldTypes.push_back(Type::Int32Ty);
// Get the GlobalVariable root.
GlobalVariable *UseRoot = M.getGlobalVariable(RootName,
Jim Laskey
committed
StructType::get(FieldTypes));
// If present and linkonce then scan for users.
Bill Wendling
committed
if (UseRoot && UseRoot->hasLinkOnceLinkage())
getGlobalVariablesUsing(UseRoot, Result);
}
/// isStringValue - Return true if the given value can be coerced to a string.
///
static bool isStringValue(Value *V) {
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) {
ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
return Init->isString();
}
} else if (Constant *C = dyn_cast<Constant>(V)) {
if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
return isStringValue(GV);
else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
if (CE->getOpcode() == Instruction::GetElementPtr) {
if (CE->getNumOperands() == 3 &&
cast<Constant>(CE->getOperand(1))->isNullValue() &&
isa<ConstantInt>(CE->getOperand(2))) {
return isStringValue(CE->getOperand(0));
}
}
}
}
return false;
}
/// getGlobalVariable - Return either a direct or cast Global value.
static GlobalVariable *getGlobalVariable(Value *V) {
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
return GV;
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
return dyn_cast<GlobalVariable>(CE->getOperand(0));
} else if (CE->getOpcode() == Instruction::GetElementPtr) {
for (unsigned int i=1; i<CE->getNumOperands(); i++) {
if (!CE->getOperand(i)->isNullValue())
return NULL;
}
return dyn_cast<GlobalVariable>(CE->getOperand(0));
}
return NULL;
}
/// isGlobalVariable - Return true if the given value can be coerced to a
/// GlobalVariable.
if (isa<GlobalVariable>(V) || isa<ConstantPointerNull>(V)) {
return true;
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
return isa<GlobalVariable>(CE->getOperand(0));
} else if (CE->getOpcode() == Instruction::GetElementPtr) {
for (unsigned int i=1; i<CE->getNumOperands(); i++) {
if (!CE->getOperand(i)->isNullValue())
return false;
}
return isa<GlobalVariable>(CE->getOperand(0));
}
}
return false;
}
Bill Wendling
committed
/// getUIntOperand - Return ith operand if it is an unsigned integer.
///
static ConstantInt *getUIntOperand(GlobalVariable *GV, unsigned i) {
// Make sure the GlobalVariable has an initializer.
if (!GV->hasInitializer()) return NULL;
// Get the initializer constant.
ConstantStruct *CI = dyn_cast<ConstantStruct>(GV->getInitializer());
if (!CI) return NULL;
// Check if there is at least i + 1 operands.
unsigned N = CI->getNumOperands();
if (i >= N) return NULL;
// Check constant.
return dyn_cast<ConstantInt>(CI->getOperand(i));
}
//===----------------------------------------------------------------------===//
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
static unsigned CountFields(DebugInfoDesc *DD) {
unsigned Count = 0;
switch (DD->getTag()) {
case DW_TAG_anchor: // AnchorDesc
// Tag
// AnchorTag
Count = 2;
break;
case DW_TAG_compile_unit: // CompileUnitDesc
// [DW_TAG_anchor]
// if (Version == 0) DebugVersion
// Language
// FileName
// Directory
// Producer
Count = 6;
// Handle cases out of sync with compiler.
if (DD->getVersion() == 0)
++Count;
break;
case DW_TAG_variable: // GlobalVariableDesc
// [DW_TAG_anchor]
// Context
// Name
// FullName
// LinkageName
// File
// Line
// TyDesc
// IsStatic
// IsDefinition
// Global
Count = 12;
break;
case DW_TAG_subprogram: // SubprogramDesc
// [DW_TAG_anchor]
// Context
// Name
// FullName
// LinkageName
// File
// Line
// TyDesc
// IsStatic
// IsDefinition
Loading
Loading full blame...