예제 #1
0
/// CreateGlobalString - Make a new global variable with an initializer that
/// has array of i8 type filled in with the nul terminated string value
/// specified.  If Name is specified, it is the name of the global variable
/// created.
Value *IRBuilderBase::CreateGlobalString(const char *Str, const Twine &Name) {
  Constant *StrConstant = ConstantArray::get(Context, Str, true);
  Module &M = *BB->getParent()->getParent();
  GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(),
                                          true, GlobalValue::InternalLinkage,
                                          StrConstant, "", 0, false);
  GV->setName(Name);
  return GV;
}
예제 #2
0
/// CreateGlobalString - Make a new global variable with an initializer that
/// has array of i8 type filled in with the nul terminated string value
/// specified.  If Name is specified, it is the name of the global variable
/// created.
Value *IRBuilderBase::CreateGlobalString(StringRef Str, const Twine &Name) {
  Constant *StrConstant = ConstantDataArray::getString(Context, Str);
  Module &M = *BB->getParent()->getParent();
  GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(),
                                          true, GlobalValue::PrivateLinkage,
                                          StrConstant);
  GV->setName(Name);
  GV->setUnnamedAddr(true);
  return GV;
}
static void defineFuncArray(Module &M, const char *LlvmArrayName,
                            const char *StartSymbol,
                            const char *EndSymbol) {
  std::vector<Constant*> Funcs;

  GlobalVariable *Array = M.getNamedGlobal(LlvmArrayName);
  if (Array) {
    readFuncList(Array, &Funcs);
    // No code should be referencing global_ctors/global_dtors,
    // because this symbol is internal to LLVM.
    Array->eraseFromParent();
  }

  Type *FuncTy = FunctionType::get(Type::getVoidTy(M.getContext()), false);
  Type *FuncPtrTy = FuncTy->getPointerTo();
  ArrayType *ArrayTy = ArrayType::get(FuncPtrTy, Funcs.size());
  GlobalVariable *NewArray =
      new GlobalVariable(M, ArrayTy, /* isConstant= */ true,
                         GlobalValue::InternalLinkage,
                         ConstantArray::get(ArrayTy, Funcs));
  setGlobalVariableValue(M, StartSymbol, NewArray);
  // We do this last so that LLVM gives NewArray the name
  // "__{init,fini}_array_start" without adding any suffixes to
  // disambiguate from the original GlobalVariable's name.  This is
  // not essential -- it just makes the output easier to understand
  // when looking at symbols for debugging.
  NewArray->setName(StartSymbol);

  // We replace "__{init,fini}_array_end" with the address of the end
  // of NewArray.  This removes the name "__{init,fini}_array_end"
  // from the output, which is not ideal for debugging.  Ideally we
  // would convert "__{init,fini}_array_end" to being a GlobalAlias
  // that points to the end of the array.  However, unfortunately LLVM
  // does not generate correct code when a GlobalAlias contains a
  // GetElementPtr ConstantExpr.
  Constant *NewArrayEnd =
      ConstantExpr::getGetElementPtr(ArrayTy, NewArray,
                                     ConstantInt::get(M.getContext(),
                                                      APInt(32, 1)));
  setGlobalVariableValue(M, EndSymbol, NewArrayEnd);
}
예제 #4
0
bool GenericToNVVM::runOnModule(Module &M) {
  // Create a clone of each global variable that has the default address space.
  // The clone is created with the global address space  specifier, and the pair
  // of original global variable and its clone is placed in the GVMap for later
  // use.

  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E;) {
    GlobalVariable *GV = &*I++;
    if (GV->getType()->getAddressSpace() == llvm::ADDRESS_SPACE_GENERIC &&
        !llvm::isTexture(*GV) && !llvm::isSurface(*GV) &&
        !llvm::isSampler(*GV) && !GV->getName().startswith("llvm.")) {
      GlobalVariable *NewGV = new GlobalVariable(
          M, GV->getValueType(), GV->isConstant(),
          GV->getLinkage(),
          GV->hasInitializer() ? GV->getInitializer() : nullptr,
          "", GV, GV->getThreadLocalMode(), llvm::ADDRESS_SPACE_GLOBAL);
      NewGV->copyAttributesFrom(GV);
      GVMap[GV] = NewGV;
    }
  }

  // Return immediately, if every global variable has a specific address space
  // specifier.
  if (GVMap.empty()) {
    return false;
  }

  // Walk through the instructions in function defitinions, and replace any use
  // of original global variables in GVMap with a use of the corresponding
  // copies in GVMap.  If necessary, promote constants to instructions.
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    if (I->isDeclaration()) {
      continue;
    }
    IRBuilder<> Builder(I->getEntryBlock().getFirstNonPHIOrDbg());
    for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE;
         ++BBI) {
      for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
           ++II) {
        for (unsigned i = 0, e = II->getNumOperands(); i < e; ++i) {
          Value *Operand = II->getOperand(i);
          if (isa<Constant>(Operand)) {
            II->setOperand(
                i, remapConstant(&M, &*I, cast<Constant>(Operand), Builder));
          }
        }
      }
    }
    ConstantToValueMap.clear();
  }

  // Copy GVMap over to a standard value map.
  ValueToValueMapTy VM;
  for (auto I = GVMap.begin(), E = GVMap.end(); I != E; ++I)
    VM[I->first] = I->second;

  // Walk through the metadata section and update the debug information
  // associated with the global variables in the default address space.
  for (NamedMDNode &I : M.named_metadata()) {
    remapNamedMDNode(VM, &I);
  }

  // Walk through the global variable  initializers, and replace any use of
  // original global variables in GVMap with a use of the corresponding copies
  // in GVMap.  The copies need to be bitcast to the original global variable
  // types, as we cannot use cvta in global variable initializers.
  for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) {
    GlobalVariable *GV = I->first;
    GlobalVariable *NewGV = I->second;

    // Remove GV from the map so that it can be RAUWed.  Note that
    // DenseMap::erase() won't invalidate any iterators but this one.
    auto Next = std::next(I);
    GVMap.erase(I);
    I = Next;

    Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType());
    // At this point, the remaining uses of GV should be found only in global
    // variable initializers, as other uses have been already been removed
    // while walking through the instructions in function definitions.
    GV->replaceAllUsesWith(BitCastNewGV);
    std::string Name = GV->getName();
    GV->eraseFromParent();
    NewGV->setName(Name);
  }
  assert(GVMap.empty() && "Expected it to be empty by now");

  return true;
}
예제 #5
0
void MetadataTransform(CallSite &CS, const TargetData *TD)
{
    Instruction *I = CS.getInstruction();
    Module *M = I->getParent()->getParent()->getParent();
    LLVMContext &Ctx = I->getContext();
    unsigned argIdx = 0;

    if (CS.arg_size() < 2)
        report_fatal_error(I, "_SYS_lti_metadata requires at least two args");

    // Parse the 'key' parameter
    ConstantInt *CI = dyn_cast<ConstantInt>(CS.getArgument(argIdx++));
    if (!CI)
        report_fatal_error(I, "Metadata key must be a constant integer.");
    uint16_t key = CI->getZExtValue();
    if (key != CI->getZExtValue())
        report_fatal_error(I, "Metadata key argument is too large.");

    // Parse the 'fmt' parameter
    std::string fmt;
    if (!GetConstantStringInfo(CS.getArgument(argIdx++), fmt))
        report_fatal_error(I, "Metadata format must be a constant string.");
    if (fmt.size() != CS.arg_size() - 2)
        report_fatal_error(I, "Length of metadata format must match number of parameters");
    if (fmt.size() == 0)
        report_fatal_error(I, "Empty metadata values are not supported");

    /*
     * Parse every other parameter according to the format string
     */

    SmallVector<Constant*, 8> Members;
    unsigned align = 1;

    for (std::string::iterator FI = fmt.begin(), FE = fmt.end();
        FI != FE; ++FI, argIdx++) {
        Constant *Arg = dyn_cast<Constant>(CS.getArgument(argIdx));
        Constant *C;
        if (!Arg)
            report_fatal_error(I, "Metadata argument " + Twine(argIdx+1) + " is not constant");

        /*
         * First, non-integer types
         */

        switch (*FI) {
            case 's': {
                std::string str;
                if (!GetConstantStringInfo(Arg, str))
                    report_fatal_error(I, "Metadata formatter 's' requires a constant string");
                Members.push_back(ConstantArray::get(Ctx, str, false));
                continue;
            }
        }
        
        /*
         * Integer types
         */

        if (Arg->getType()->isPointerTy())
            Arg = ConstantExpr::getPointerCast(Arg, Type::getInt32Ty(Ctx));

        if (!Arg->getType()->isIntegerTy())
            report_fatal_error(I, "Metadata argument " + Twine(argIdx+1) +
                " can't be converted to an integer type.");

        switch (*FI) {

            case 'b':
                C = ConstantExpr::getIntegerCast(Arg, Type::getInt8Ty(Ctx), true);
                break;

            case 'B':
                C = ConstantExpr::getIntegerCast(Arg, Type::getInt8Ty(Ctx), false);
                break;

            case 'h':
                C = ConstantExpr::getIntegerCast(Arg, Type::getInt16Ty(Ctx), true);
                break;

            case 'H':
                C = ConstantExpr::getIntegerCast(Arg, Type::getInt16Ty(Ctx), false);
                break;

            case 'i':
                C = ConstantExpr::getIntegerCast(Arg, Type::getInt32Ty(Ctx), true);
                break;

            case 'I':
                C = ConstantExpr::getIntegerCast(Arg, Type::getInt32Ty(Ctx), false);
                break;

            default:
                report_fatal_error(I, "Unsupported format character '" + Twine(*FI) + "' in metadata");
        }

        align = std::max(align, TD->getABITypeAlignment(C->getType()));
        Members.push_back(C);
    }

    Constant *Struct = ConstantStruct::getAnon(Members);

    /*
     * Install this metadata item as a global variable in a special section
     */

    GlobalVariable *GV = new GlobalVariable(*M, Struct->getType(),
        true, GlobalValue::ExternalLinkage, Struct, "", 0, false);

    GV->setAlignment(align);
    GV->setName(SVMDecorations::META + Twine(key) + SVMDecorations::SEPARATOR);
    GV->setSection(".metadata");

    // Remove the original _SYS_lti_metadata() call
    I->eraseFromParent();
}
예제 #6
0
static PointerType *buildTlsTemplate(Module &M, std::vector<VarInfo> *TlsVars) {
  std::vector<Type*> FieldBssTypes;
  std::vector<Type*> FieldInitTypes;
  std::vector<Constant*> FieldInitValues;
  PassState State(&M);

  for (Module::global_iterator GV = M.global_begin();
       GV != M.global_end();
       ++GV) {
    if (GV->isThreadLocal()) {
      if (!GV->hasInitializer()) {
        // Since this is a whole-program transformation, "extern" TLS
        // variables are not allowed at this point.
        report_fatal_error(std::string("TLS variable without an initializer: ")
                           + GV->getName());
      }
      if (!GV->getInitializer()->isNullValue()) {
        addVarToTlsTemplate(&State, &FieldInitTypes,
                            &FieldInitValues, GV);
        VarInfo Info;
        Info.TlsVar = GV;
        Info.IsBss = false;
        Info.TemplateIndex = FieldInitTypes.size() - 1;
        TlsVars->push_back(Info);
      }
    }
  }
  // Handle zero-initialized TLS variables in a second pass, because
  // these should follow non-zero-initialized TLS variables.
  for (Module::global_iterator GV = M.global_begin();
       GV != M.global_end();
       ++GV) {
    if (GV->isThreadLocal() && GV->getInitializer()->isNullValue()) {
      addVarToTlsTemplate(&State, &FieldBssTypes, NULL, GV);
      VarInfo Info;
      Info.TlsVar = GV;
      Info.IsBss = true;
      Info.TemplateIndex = FieldBssTypes.size() - 1;
      TlsVars->push_back(Info);
    }
  }
  // Add final alignment padding so that
  //   (struct tls_struct *) __nacl_read_tp() - 1
  // gives the correct, aligned start of the TLS variables given the
  // x86-style layout we are using.  This requires some more bytes to
  // be memset() to zero at runtime.  This wastage doesn't seem
  // important gives that we're not trying to optimize packing by
  // reordering to put similarly-aligned variables together.
  padToAlignment(&State, &FieldBssTypes, NULL, State.Alignment);

  // We create the TLS template structs as "packed" because we insert
  // alignment padding ourselves, and LLVM's implicit insertion of
  // padding would interfere with ours.  tls_bss_template can start at
  // a non-aligned address immediately following the last field in
  // tls_init_template.
  StructType *InitTemplateType =
      StructType::create(M.getContext(), "tls_init_template");
  InitTemplateType->setBody(FieldInitTypes, /*isPacked=*/true);
  StructType *BssTemplateType =
      StructType::create(M.getContext(), "tls_bss_template");
  BssTemplateType->setBody(FieldBssTypes, /*isPacked=*/true);

  StructType *TemplateType = StructType::create(M.getContext(), "tls_struct");
  SmallVector<Type*, 2> TemplateTopFields;
  TemplateTopFields.push_back(InitTemplateType);
  TemplateTopFields.push_back(BssTemplateType);
  TemplateType->setBody(TemplateTopFields, /*isPacked=*/true);
  PointerType *TemplatePtrType = PointerType::get(TemplateType, 0);

  // We define the following symbols, which are the same as those
  // defined by NaCl's original customized binutils linker scripts:
  //   __tls_template_start
  //   __tls_template_tdata_end
  //   __tls_template_end
  // We also define __tls_template_alignment, which was not defined by
  // the original linker scripts.

  const char *StartSymbol = "__tls_template_start";
  Constant *TemplateData = ConstantStruct::get(InitTemplateType,
                                               FieldInitValues);
  GlobalVariable *TemplateDataVar =
      new GlobalVariable(M, InitTemplateType, /*isConstant=*/true,
                         GlobalValue::InternalLinkage, TemplateData);
  setGlobalVariableValue(M, StartSymbol, TemplateDataVar);
  TemplateDataVar->setName(StartSymbol);

  Constant *TdataEnd = ConstantExpr::getGetElementPtr(
      TemplateDataVar,
      ConstantInt::get(M.getContext(), APInt(32, 1)));
  setGlobalVariableValue(M, "__tls_template_tdata_end", TdataEnd);

  Constant *TotalEnd = ConstantExpr::getGetElementPtr(
      ConstantExpr::getBitCast(TemplateDataVar, TemplatePtrType),
      ConstantInt::get(M.getContext(), APInt(32, 1)));
  setGlobalVariableValue(M, "__tls_template_end", TotalEnd);

  const char *AlignmentSymbol = "__tls_template_alignment";
  Type *i32 = Type::getInt32Ty(M.getContext());
  GlobalVariable *AlignmentVar = new GlobalVariable(
      M, i32, /*isConstant=*/true,
      GlobalValue::InternalLinkage,
      ConstantInt::get(M.getContext(), APInt(32, State.Alignment)));
  setGlobalVariableValue(M, AlignmentSymbol, AlignmentVar);
  AlignmentVar->setName(AlignmentSymbol);

  return TemplatePtrType;
}