Skip to content
MachineModuleInfo.cpp 60.1 KiB
Newer Older
Jim Laskey's avatar
Jim Laskey committed
//===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===//
Jim Laskey's avatar
Jim Laskey committed
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
Jim Laskey's avatar
Jim Laskey committed
//
//===----------------------------------------------------------------------===//

Jim Laskey's avatar
Jim Laskey committed
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
Jim Laskey's avatar
Jim Laskey committed
#include "llvm/Target/TargetOptions.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"
Jim Laskey's avatar
Jim Laskey committed
using namespace llvm;
Jim Laskey's avatar
Jim Laskey committed

// Handle the Pass registration stuff necessary to use TargetData's.
static RegisterPass<MachineModuleInfo>
X("machinemoduleinfo", "Module Information");
Devang Patel's avatar
Devang Patel committed
char MachineModuleInfo::ID = 0;
//===----------------------------------------------------------------------===//

/// 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.
static void
getGlobalVariablesUsing(Module &M, const std::string &RootName,
                        std::vector<GlobalVariable*> &Result) {
Reid Spencer's avatar
Reid Spencer committed
  FieldTypes.push_back(Type::Int32Ty);
  FieldTypes.push_back(Type::Int32Ty);
  // Get the GlobalVariable root.
  GlobalVariable *UseRoot = M.getGlobalVariable(RootName,

  // If present and linkonce then scan for users.
  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;
}

Jim Laskey's avatar
Jim Laskey committed
/// getGlobalVariable - Return either a direct or cast Global value.
Jim Laskey's avatar
Jim Laskey committed
static GlobalVariable *getGlobalVariable(Value *V) {
  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
    return GV;
  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
Reid Spencer's avatar
Reid Spencer committed
    if (CE->getOpcode() == Instruction::BitCast) {
      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));
Jim Laskey's avatar
Jim Laskey committed
/// isGlobalVariable - Return true if the given value can be coerced to a
Jim Laskey's avatar
Jim Laskey committed
static bool isGlobalVariable(Value *V) {
  if (isa<GlobalVariable>(V) || isa<ConstantPointerNull>(V)) {
    return true;
  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
Reid Spencer's avatar
Reid Spencer committed
    if (CE->getOpcode() == Instruction::BitCast) {
      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));
/// 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));
}

//===----------------------------------------------------------------------===//

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...