<commit_before>/*
 * MusicBrainz -- The Internet music metadatabase
 *
 * Copyright (C) 2006 Lukas Lalinsky
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA	 02111-1307	 USA
 */

// TODO: support for namespaces and full MMD

#include <string>
#include <iostream>
#include <string.h>
#include <musicbrainz3/utils.h>
#include <musicbrainz3/mbxmlparser.h>
#include "xmlParser/xmlParser.h"

using namespace std;
using namespace MusicBrainz;

static bool
getBoolAttribute(XMLNode node, string name)
{
	const char *value = node.getAttribute(name.c_str());
	return value ? value == "true" : false;
}

static int
getIntAttribute(XMLNode node, string name, int def = 0)
{
	const char *value = node.getAttribute(name.c_str());
	return value ? atoi(value) : def;
}

static string
getTextAttribute(XMLNode node, string name, string def = "")
{
	const char *value = node.getAttribute(name.c_str());
	return value ? string(value) : string(def);
}

static string
getText(XMLNode node)
{
	string text;
	for (int i = 0; i < node.nText(); i++)
		text += node.getText(i);
	return text;
}

static int
getInt(XMLNode node, int def = 0)
{
	string text = getText(node);
	return text.empty() ? def : atoi(text.c_str());
}

static string
getUriAttr(XMLNode node, string name, string ns = NS_MMD_1)
{
	string text = getTextAttribute(node, name);
	if (text.empty())
		return text;
	return ns + extractFragment(text);
}

static vector<string>
getUriListAttr(XMLNode node, string name, string ns = NS_MMD_1)
{
	vector<string> uriList;
	string text = getTextAttribute(node, name);
	if (text.empty())
		return uriList;
	string::size_type pos = 0;
	while (pos < text.size()) {
		string::size_type end = text.find(' ', pos);
		if (pos == end)
			break;
		string word = text.substr(pos, end);
		uriList.push_back(ns + word);
		pos = text.find_first_not_of(' ', end);
	}
	return uriList;
}

static void addArtistsToList(XMLNode listNode, ArtistList &resultList);
static void addArtistAliasesToList(XMLNode listNode, ArtistAliasList &resultList);
static void addDiscsToList(XMLNode listNode, DiscList &resultList);
static void addReleasesToList(XMLNode listNode, ReleaseList &resultList);
static void addReleaseEventsToList(XMLNode listNode, ReleaseEventList &resultList);
static void addTracksToList(XMLNode listNode, TrackList &resultList);

static Artist *
createArtist(XMLNode artistNode)
{
	Artist *artist = new Artist(getTextAttribute(artistNode, "id"));
	string type = getTextAttribute(artistNode, "type");
	if (!type.empty())
		artist->setType(NS_MMD_1 + type);
	for (int i = 0; i < artistNode.nChildNode(); i++) {
		XMLNode node = artistNode.getChildNode(i);
		string name = node.getName();
		if (name == "name") {
			artist->setName(getText(node));
		}
		else if (name == "sort-name") {
			artist->setSortName(getText(node));
		}
		else if (name == "disambiguation") {
			artist->setDisambiguation(getText(node));
		}
		else if (name == "life-span") {
			const char *begin = node.getAttribute("begin");
			const char *end = node.getAttribute("end");
			if (begin)
				artist->setBeginDate(string(begin));
			if (end)
				artist->setEndDate(string(end));
		}
		else if (name == "alias-list") {
			addArtistAliasesToList(node, artist->getAliases());
		}
	}
	return artist;
}

static ArtistAlias *
createArtistAlias(XMLNode node)
{
	ArtistAlias *alias = new ArtistAlias();
	alias->setType(getUriAttr(node, "type"));
	alias->setScript(getTextAttribute(node, "script"));
	alias->setValue(getText(node));
	return alias;
}

static Release *
createRelease(XMLNode releaseNode)
{
	Release *release = new Release(getTextAttribute(releaseNode, "id"));
	for (int i = 0; i < releaseNode.nChildNode(); i++) {
		XMLNode node = releaseNode.getChildNode(i);
		string name = node.getName();
		if (name == "title") {
			release->setTitle(getText(node));
		}
		else if (name == "text-representation") {
			release->setTextLanguage(getTextAttribute(node, "language"));
			release->setTextScript(getTextAttribute(node, "script"));
		}
		else if (name == "asin") {
			release->setAsin(getText(node));
		}
		else if (name == "artist") {
			release->setArtist(createArtist(node));
		}
		else if (name == "release-event-list") {
			addReleaseEventsToList(node, release->getReleaseEvents());
		}
		else if (name == "disc-list") {
			addDiscsToList(node, release->getDiscs());
		}
		else if (name == "track-list") {
			release->setTracksOffset(getIntAttribute(node, "offset"));
			addTracksToList(node, release->getTracks());
		}
/*		else if (name == "relation-list") {
			release->setTitle(getText(node));
		}*/
	}
	return release;
}

static Track *
createTrack(XMLNode trackNode)
{
	string id = trackNode.getAttribute("id");
	Track *track = new Track(id);
	for (int i = 0; i < trackNode.nChildNode(); i++) {
		XMLNode node = trackNode.getChildNode(i);
		string name = node.getName();
		if (name == "title") {
			track->setTitle(getText(node));
		}
		else if (name == "artist") {
			track->setArtist(createArtist(node));
		}
		else if (name == "duration") {
			track->setDuration(getInt(node));
		}
	}
	return track;
}

static User *
createUser(XMLNode userNode)
{
	User *user = new User();
	vector<string> typeList = getUriListAttr(userNode, "type", NS_EXT_1);
	for (vector<string>::iterator i = typeList.begin(); i != typeList.end(); i++)
		user->addType(*i);
	for (int i = 0; i < userNode.nChildNode(); i++) {
		XMLNode node = userNode.getChildNode(i);
		string name = node.getName();
		if (name == "name") {
			user->setName(getText(node));
		}
		else if (name == "ext:nag") {
			user->setShowNag(getBoolAttribute(node, "show"));
		}
	}
	return user;
}

static Disc *
createDisc(XMLNode discNode)
{
	Disc *disc = new Disc(getTextAttribute(discNode, "id"));
	return disc;
}

static ReleaseEvent *
createReleaseEvent(XMLNode releaseEventNode)
{
	ReleaseEvent *releaseEvent =
		new ReleaseEvent(getTextAttribute(releaseEventNode, "country"),
						 getTextAttribute(releaseEventNode, "date"));
	return releaseEvent;
}

static void
addArtistResults(XMLNode listNode, ArtistResultList &resultList)
{
}

static void
addReleaseResults(XMLNode listNode, ReleaseResultList &resultList)
{
}

static void
addTrackResults(XMLNode listNode, TrackResultList &resultList)
{
}

template<typename T, typename TL>
static void
addToList(XMLNode listNode, TL &resultList, T *(*creator)(XMLNode))
{
	for (int i = 0; i < listNode.nChildNode(); i++) {
		XMLNode node = listNode.getChildNode(i);
		resultList.push_back(creator(node));
	}
}

static void
addArtistsToList(XMLNode listNode, ArtistList &resultList)
{
	addToList<Artist, ArtistList>(listNode, resultList, &createArtist);
}

static void
addArtistAliasesToList(XMLNode listNode, ArtistAliasList &resultList)
{
	addToList<ArtistAlias, ArtistAliasList>(listNode, resultList, &createArtistAlias);
}

static void
addDiscsToList(XMLNode listNode, DiscList &resultList)
{
	addToList<Disc, DiscList>(listNode, resultList, &createDisc);
}

static void
addReleasesToList(XMLNode listNode, ReleaseList &resultList)
{
	addToList<Release, ReleaseList>(listNode, resultList, &createRelease);
}

static void
addReleaseEventsToList(XMLNode listNode, ReleaseEventList &resultList)
{
	addToList<ReleaseEvent, ReleaseEventList>(listNode, resultList, &createReleaseEvent);
}

static void
addTracksToList(XMLNode listNode, TrackList &resultList)
{
	addToList<Track, TrackList>(listNode, resultList, &createTrack);
}

static void
addUsersToList(XMLNode listNode, UserList &resultList)
{
	addToList<User, UserList>(listNode, resultList, &createUser);
}

MbXmlParser::MbXmlParser()
{
}

Metadata *
MbXmlParser::parse(const std::string &data)
{
	XMLNode root = XMLNode::parseString(data.c_str(), "metadata");

	if (root.isEmpty() || root.getName() != string("metadata")) {
		throw ParseError();
	}

	Metadata *md = new Metadata();
	try {
		for (int i = 0; i < root.nChildNode(); i++) {
			XMLNode node = root.getChildNode(i);
			string name = node.getName();
			if (name == string("artist")) {
				md->setArtist(createArtist(node));
			}
			else if (name == string("track")) {
				md->setTrack(createTrack(node));
			}
			else if (name == string("release")) {
				md->setRelease(createRelease(node));
			}
			else if (name == string("artist-list")) {
				addArtistResults(node, md->getArtistResults());
			}
			else if (name == string("track-list")) {
				addTrackResults(node, md->getTrackResults());
			}
			else if (name == string("release-list")) {
				addReleaseResults(node, md->getReleaseResults());
			}
			else if (name == string("ext:user-list")) {
				addUsersToList(node, md->getUserList());
			}
		}
	}
	catch (...) {
		delete md;
		throw ParseError();
	}

	return md;
}

<commit_msg>Internal functions renaming.<commit_after>/*
 * MusicBrainz -- The Internet music metadatabase
 *
 * Copyright (C) 2006 Lukas Lalinsky
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA	 02111-1307	 USA
 */

// TODO: support for namespaces and full MMD

#include <string>
#include <iostream>
#include <string.h>
#include <musicbrainz3/utils.h>
#include <musicbrainz3/mbxmlparser.h>
#include "xmlParser/xmlParser.h"

using namespace std;
using namespace MusicBrainz;

static bool
getBoolAttr(XMLNode node, string name)
{
	const char *value = node.getAttribute(name.c_str());
	return value ? value == "true" : false;
}

static int
getIntAttr(XMLNode node, string name, int def = 0)
{
	const char *value = node.getAttribute(name.c_str());
	return value ? atoi(value) : def;
}

static string
getTextAttr(XMLNode node, string name, string def = "")
{
	const char *value = node.getAttribute(name.c_str());
	return value ? string(value) : string(def);
}

static string
getUriAttr(XMLNode node, string name, string ns = NS_MMD_1)
{
	const char *value = node.getAttribute(name.c_str());
	if (!value)
		return string();
	string text = string(value);
	return ns + extractFragment(text);
}

static vector<string>
getUriListAttr(XMLNode node, string name, string ns = NS_MMD_1)
{
	vector<string> uriList;
	const char *value = node.getAttribute(name.c_str());
	if (!value)
		return uriList;
	string text = string(value);
	string::size_type pos = 0;
	while (pos < text.size()) {
		string::size_type end = text.find(' ', pos);
		if (pos == end)
			break;
		string word = extractFragment(text.substr(pos, end));
		uriList.push_back(ns + word);
		pos = text.find_first_not_of(' ', end);
	}
	return uriList;
}

static string
getText(XMLNode node)
{
	string text;
	for (int i = 0; i < node.nText(); i++)
		text += node.getText(i);
	return text;
}

static int
getInt(XMLNode node, int def = 0)
{
	string text = getText(node);
	return text.empty() ? def : atoi(text.c_str());
}

static void addArtistsToList(XMLNode listNode, ArtistList &resultList);
static void addArtistAliasesToList(XMLNode listNode, ArtistAliasList &resultList);
static void addDiscsToList(XMLNode listNode, DiscList &resultList);
static void addReleasesToList(XMLNode listNode, ReleaseList &resultList);
static void addReleaseEventsToList(XMLNode listNode, ReleaseEventList &resultList);
static void addTracksToList(XMLNode listNode, TrackList &resultList);

static Artist *
createArtist(XMLNode artistNode)
{
	Artist *artist = new Artist(getTextAttr(artistNode, "id"));
	artist->setType(getUriAttr(artistNode, "type"));
	for (int i = 0; i < artistNode.nChildNode(); i++) {
		XMLNode node = artistNode.getChildNode(i);
		string name = node.getName();
		if (name == "name") {
			artist->setName(getText(node));
		}
		else if (name == "sort-name") {
			artist->setSortName(getText(node));
		}
		else if (name == "disambiguation") {
			artist->setDisambiguation(getText(node));
		}
		else if (name == "life-span") {
			const char *begin = node.getAttribute("begin");
			const char *end = node.getAttribute("end");
			if (begin)
				artist->setBeginDate(string(begin));
			if (end)
				artist->setEndDate(string(end));
		}
		else if (name == "alias-list") {
			addArtistAliasesToList(node, artist->getAliases());
		}
	}
	return artist;
}

static ArtistAlias *
createArtistAlias(XMLNode node)
{
	ArtistAlias *alias = new ArtistAlias();
	alias->setType(getUriAttr(node, "type"));
	alias->setScript(getTextAttr(node, "script"));
	alias->setValue(getText(node));
	return alias;
}

static Release *
createRelease(XMLNode releaseNode)
{
	Release *release = new Release(getTextAttr(releaseNode, "id"));
	for (int i = 0; i < releaseNode.nChildNode(); i++) {
		XMLNode node = releaseNode.getChildNode(i);
		string name = node.getName();
		if (name == "title") {
			release->setTitle(getText(node));
		}
		else if (name == "text-representation") {
			release->setTextLanguage(getTextAttr(node, "language"));
			release->setTextScript(getTextAttr(node, "script"));
		}
		else if (name == "asin") {
			release->setAsin(getText(node));
		}
		else if (name == "artist") {
			release->setArtist(createArtist(node));
		}
		else if (name == "release-event-list") {
			addReleaseEventsToList(node, release->getReleaseEvents());
		}
		else if (name == "disc-list") {
			addDiscsToList(node, release->getDiscs());
		}
		else if (name == "track-list") {
			release->setTracksOffset(getIntAttr(node, "offset"));
			addTracksToList(node, release->getTracks());
		}
/*		else if (name == "relation-list") {
			release->setTitle(getText(node));
		}*/
	}
	return release;
}

static Track *
createTrack(XMLNode trackNode)
{
	string id = trackNode.getAttribute("id");
	Track *track = new Track(id);
	for (int i = 0; i < trackNode.nChildNode(); i++) {
		XMLNode node = trackNode.getChildNode(i);
		string name = node.getName();
		if (name == "title") {
			track->setTitle(getText(node));
		}
		else if (name == "artist") {
			track->setArtist(createArtist(node));
		}
		else if (name == "duration") {
			track->setDuration(getInt(node));
		}
	}
	return track;
}

static User *
createUser(XMLNode userNode)
{
	User *user = new User();
	vector<string> typeList = getUriListAttr(userNode, "type", NS_EXT_1);
	for (vector<string>::iterator i = typeList.begin(); i != typeList.end(); i++)
		user->addType(*i);
	for (int i = 0; i < userNode.nChildNode(); i++) {
		XMLNode node = userNode.getChildNode(i);
		string name = node.getName();
		if (name == "name") {
			user->setName(getText(node));
		}
		else if (name == "ext:nag") {
			user->setShowNag(getBoolAttr(node, "show"));
		}
	}
	return user;
}

static Disc *
createDisc(XMLNode discNode)
{
	Disc *disc = new Disc(getTextAttr(discNode, "id"));
	return disc;
}

static ReleaseEvent *
createReleaseEvent(XMLNode releaseEventNode)
{
	ReleaseEvent *releaseEvent =
		new ReleaseEvent(getTextAttr(releaseEventNode, "country"),
						 getTextAttr(releaseEventNode, "date"));
	return releaseEvent;
}

static void
addArtistResults(XMLNode listNode, ArtistResultList &resultList)
{
}

static void
addReleaseResults(XMLNode listNode, ReleaseResultList &resultList)
{
}

static void
addTrackResults(XMLNode listNode, TrackResultList &resultList)
{
}

template<typename T, typename TL>
static void
addToList(XMLNode listNode, TL &resultList, T *(*creator)(XMLNode))
{
	for (int i = 0; i < listNode.nChildNode(); i++) {
		XMLNode node = listNode.getChildNode(i);
		resultList.push_back(creator(node));
	}
}

static void
addArtistsToList(XMLNode listNode, ArtistList &resultList)
{
	addToList<Artist, ArtistList>(listNode, resultList, &createArtist);
}

static void
addArtistAliasesToList(XMLNode listNode, ArtistAliasList &resultList)
{
	addToList<ArtistAlias, ArtistAliasList>(listNode, resultList, &createArtistAlias);
}

static void
addDiscsToList(XMLNode listNode, DiscList &resultList)
{
	addToList<Disc, DiscList>(listNode, resultList, &createDisc);
}

static void
addReleasesToList(XMLNode listNode, ReleaseList &resultList)
{
	addToList<Release, ReleaseList>(listNode, resultList, &createRelease);
}

static void
addReleaseEventsToList(XMLNode listNode, ReleaseEventList &resultList)
{
	addToList<ReleaseEvent, ReleaseEventList>(listNode, resultList, &createReleaseEvent);
}

static void
addTracksToList(XMLNode listNode, TrackList &resultList)
{
	addToList<Track, TrackList>(listNode, resultList, &createTrack);
}

static void
addUsersToList(XMLNode listNode, UserList &resultList)
{
	addToList<User, UserList>(listNode, resultList, &createUser);
}

MbXmlParser::MbXmlParser()
{
}

Metadata *
MbXmlParser::parse(const std::string &data)
{
	XMLNode root = XMLNode::parseString(data.c_str(), "metadata");

	if (root.isEmpty() || root.getName() != string("metadata")) {
		throw ParseError();
	}

	Metadata *md = new Metadata();
	try {
		for (int i = 0; i < root.nChildNode(); i++) {
			XMLNode node = root.getChildNode(i);
			string name = node.getName();
			if (name == string("artist")) {
				md->setArtist(createArtist(node));
			}
			else if (name == string("track")) {
				md->setTrack(createTrack(node));
			}
			else if (name == string("release")) {
				md->setRelease(createRelease(node));
			}
			else if (name == string("artist-list")) {
				addArtistResults(node, md->getArtistResults());
			}
			else if (name == string("track-list")) {
				addTrackResults(node, md->getTrackResults());
			}
			else if (name == string("release-list")) {
				addReleaseResults(node, md->getReleaseResults());
			}
			else if (name == string("ext:user-list")) {
				addUsersToList(node, md->getUserList());
			}
		}
	}
	catch (...) {
		delete md;
		throw ParseError();
	}

	return md;
}

<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkDataNode.h"

#include <vtkWindow.h>
#include "mitkVtkPropRenderer.h"

#include "mitkTestingMacros.h"
#include "mitkGlobalInteraction.h"

#include <iostream>

//Basedata Test
#include <mitkGeometryData.h>
#include <mitkPlaneGeometryData.h>
#include <mitkManufacturerLogo.h>
#include <mitkPointSet.h>
#include <mitkImage.h>
#include <mitkSurface.h>

//Mapper Test
#include <mitkPlaneGeometryDataMapper2D.h>
#include <mitkImageVtkMapper2D.h>
#include <mitkSurfaceVtkMapper2D.h>

#include <mitkPlaneGeometryDataVtkMapper3D.h>
#include <mitkPointSetVtkMapper3D.h>
#include <mitkPointSetVtkMapper2D.h>
#include <mitkSurfaceVtkMapper3D.h>
#include <mitkVolumeDataVtkMapper3D.h>

//Interactors
#include <mitkPointSetDataInteractor.h>

//Propertylist Test
#include <mitkImageGenerator.h>

/**
 *  Simple example for a test for the (non-existent) class "DataNode".
 *
 *  argc and argv are the command line parameters which were passed to
 *  the ADD_TEST command in the CMakeLists.txt file. For the automatic
 *  tests, argv is either empty for the simple tests or contains the filename
 *  of a test image for the image tests (see CMakeLists.txt).
 */
class mitkDataNodeTestClass { public:

static void TestDataSetting(mitk::DataNode::Pointer dataNode)
{

  mitk::BaseData::Pointer baseData;

  //NULL pointer Test
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a NULL pointer was set correctly" )

  baseData = mitk::GeometryData::New();
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a GeometryData object was set correctly" )

  baseData = mitk::PlaneGeometryData::New();
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a PlaneGeometryData object was set correctly" )

  baseData = mitk::ManufacturerLogo::New();
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a ManufacturerLogo object was set correctly" )

  baseData = mitk::PointSet::New();
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a PointSet object was set correctly" )

  baseData = mitk::Image::New();
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Image object was set correctly" )

  baseData = mitk::Surface::New();
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Surface object was set correctly" )
}
static void TestMapperSetting(mitk::DataNode::Pointer dataNode)
{
  //tests the SetMapper() method
  //in dataNode is a mapper vector which can be accessed by index
  //in this test method we use only slot 0 (filled with null) and slot 1
  //so we also test the destructor of the mapper classes
  mitk::Mapper::Pointer mapper;

  dataNode->SetMapper(0,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(0), "Testing if a NULL pointer was set correctly" )

  mapper = mitk::PlaneGeometryDataMapper2D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PlaneGeometryDataMapper2D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::ImageVtkMapper2D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a ImageVtkMapper2D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::PointSetVtkMapper2D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PointSetVtkMapper2D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::SurfaceVtkMapper2D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SurfaceGLMapper2D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::PlaneGeometryDataVtkMapper3D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PlaneGeometryDataVtkMapper3D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::PointSetVtkMapper3D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PointSetVtkMapper3D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::SurfaceVtkMapper3D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SurfaceVtkMapper3D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::VolumeDataVtkMapper3D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a VolumeDataVtkMapper3D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
}

static void TestInteractorSetting(mitk::DataNode::Pointer dataNode)
{

  //this method tests the SetInteractor() and GetInteractor methods
  //the DataInteractor base class calls the DataNode->SetInteractor method

  mitk::DataInteractor::Pointer interactor;

  MITK_TEST_CONDITION( interactor == dataNode->GetDataInteractor(), "Testing if a NULL pointer was set correctly (DataInteractor)" )

  interactor = mitk::PointSetDataInteractor::New();
  interactor->SetEventConfig("PointSetConfig.xml");
  interactor->SetDataNode(dataNode);
  MITK_TEST_CONDITION( interactor == dataNode->GetDataInteractor(), "Testing if a PointSetDataInteractor was set correctly" )

  interactor = mitk::PointSetDataInteractor::New();
  dataNode->SetDataInteractor(interactor);
  MITK_TEST_CONDITION( interactor == dataNode->GetDataInteractor(), "Testing if a PointSetDataInteractor was set correctly" )
}
static void TestPropertyList(mitk::DataNode::Pointer dataNode)
{

  mitk::PropertyList::Pointer propertyList =  dataNode->GetPropertyList();

  MITK_TEST_CONDITION(dataNode->GetPropertyList() != NULL, "Testing if the constructor set the propertylist" )

  dataNode->SetIntProperty("int", -31337);
  int x;
  dataNode->GetIntProperty("int", x);
  MITK_TEST_CONDITION(x == -31337, "Testing Set/GetIntProperty");

  dataNode->SetBoolProperty("bool", true);
  bool b;
  dataNode->GetBoolProperty("bool", b);
  MITK_TEST_CONDITION(b == true, "Testing Set/GetBoolProperty");
  dataNode->SetFloatProperty("float", -31.337);
  float y;
  dataNode->GetFloatProperty("float", y);
  MITK_TEST_CONDITION(y - -31.337 < 0.01, "Testing Set/GetFloatProperty");
  double yd = 0;
  dataNode->GetDoubleProperty("float", yd);
  MITK_TEST_CONDITION(mitk::Equal(yd, static_cast<double>(y)), "Testing GetDoubleProperty");
  dataNode->SetStringProperty("string", "MITK");
  std::string s = "GANZVIELPLATZ";
  dataNode->GetStringProperty("string", s);
  MITK_TEST_CONDITION(s == "MITK", "Testing Set/GetStringProperty");

  std::string name = "MyTestName";
  dataNode->SetName(name.c_str());
  MITK_TEST_CONDITION(dataNode->GetName() == name, "Testing Set/GetName");
  name = "MySecondTestName";
  dataNode->SetName(name);
  MITK_TEST_CONDITION(dataNode->GetName() == name, "Testing Set/GetName(std::string)");

  MITK_TEST_CONDITION(propertyList == dataNode->GetPropertyList(), "Testing if the propertylist has changed during the last tests" )
}

static void TestSelected(mitk::DataNode::Pointer dataNode)
{
  vtkRenderWindow *renderWindow = vtkRenderWindow::New();

  mitk::VtkPropRenderer::Pointer base = mitk::VtkPropRenderer::New( "the first renderer", renderWindow, mitk::RenderingManager::GetInstance() );

  //with BaseRenderer==Null
  MITK_TEST_CONDITION(!dataNode->IsSelected(), "Testing if this node is not set as selected" )

  dataNode->SetSelected(true);
  MITK_TEST_CONDITION(dataNode->IsSelected(), "Testing if this node is set as selected" )
  dataNode->SetSelected(false);

  dataNode->SetSelected(true,base);

  MITK_TEST_CONDITION(dataNode->IsSelected(base), "Testing if this node with right base renderer is set as selected" )

  //Delete RenderWindow correctly
  renderWindow->Delete();

}
static void TestGetMTime(mitk::DataNode::Pointer dataNode)
{
  unsigned long time;
  time = dataNode->GetMTime();
  mitk::PointSet::Pointer pointSet = mitk::PointSet::New();

  dataNode->SetData(pointSet);
  MITK_TEST_CONDITION( time != dataNode->GetMTime(), "Testing if the node timestamp is updated after adding data to the node" )

  mitk::Point3D point;
  point.Fill(3.0);
  pointSet->SetPoint(0,point);

  //less or equal because dataNode timestamp is little later then the basedata timestamp
  MITK_TEST_CONDITION( pointSet->GetMTime() <= dataNode->GetMTime(), "Testing if the node timestamp is updated after base data was modified" )

  // testing if changing anything in the property list also sets the node in a modified state
  unsigned long lastModified = dataNode->GetMTime();
  dataNode->SetIntProperty("testIntProp", 2344);
  MITK_TEST_CONDITION( lastModified <= dataNode->GetMTime(), "Testing if the node timestamp is updated after property list was modified" )

}
static void TestSetDataUnderPropertyChange(mitk::DataNode::Pointer dataNode)
{
  mitk::Image::Pointer image = mitk::Image::New();
  mitk::Image::Pointer additionalImage = mitk::Image::New();

  mitk::DataNode::Pointer additionalDataNode = mitk::DataNode::New();

  image = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(3u, 3u);

  additionalDataNode->SetData(image);

  float outlineWidth = 0;
  MITK_TEST_CONDITION(mitk::Equal(outlineWidth,1.0), "Testing if the SetData set the default propertylist" )

  additionalDataNode->SetProperty("outline width", mitk::FloatProperty::New( 42.0 ));
  additionalDataNode->SetData(image);
  additionalDataNode->GetPropertyValue("outline width", outlineWidth);

  MITK_TEST_CONDITION(mitk::Equal(outlineWidth,42.0), "Testing if the SetData does not set anything if imagedata is identical" )

  additionalDataNode->SetData(additionalImage);
  additionalDataNode->GetPropertyValue("outline width", outlineWidth);

  MITK_TEST_CONDITION(mitk::Equal(outlineWidth,42.0), "Testing if the SetData does not set the default propertylist if imagedata is already set" )

  mitk::Surface::Pointer additionalSurface = mitk::Surface::New();
  additionalDataNode->SetData(additionalSurface);
  //additionalDataNode->GetPropertyValue("outline width", &outlineWidth);

  MITK_TEST_CONDITION(additionalDataNode->GetPropertyValue("outline width", outlineWidth) == false, "Testing if the SetData sets the default propertylist if some new datatype is loaded" )
}
}; //mitkDataNodeTestClass

int mitkDataNodeTest(int /* argc */, char* /*argv*/[])
{
  // always start with this!
  MITK_TEST_BEGIN("DataNode")

  // Global interaction must(!) be initialized
  mitk::GlobalInteraction::GetInstance()->Initialize("global");

  // let's create an object of our class
  mitk::DataNode::Pointer myDataNode = mitk::DataNode::New();

  // first test: did this work?
  // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
  // it makes no sense to continue without an object.
  MITK_TEST_CONDITION_REQUIRED(myDataNode.IsNotNull(),"Testing instantiation")

  //test setData() Method
  mitkDataNodeTestClass::TestDataSetting(myDataNode);
  mitkDataNodeTestClass::TestMapperSetting(myDataNode);
  mitkDataNodeTestClass::TestSetDataUnderPropertyChange(myDataNode);
  //
  //note, that no data is set to the dataNode
  mitkDataNodeTestClass::TestInteractorSetting(myDataNode);
  mitkDataNodeTestClass::TestPropertyList(myDataNode);
  mitkDataNodeTestClass::TestSelected(myDataNode);
  mitkDataNodeTestClass::TestGetMTime(myDataNode);

  // write your own tests here and use the macros from mitkTestingMacros.h !!!
  // do not write to std::cout and do not return from this function yourself!

  // always end with this!
  MITK_TEST_END()
}

<commit_msg>cleanup<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkDataNode.h"

#include <vtkWindow.h>
#include "mitkVtkPropRenderer.h"

#include "mitkTestingMacros.h"
#include "mitkGlobalInteraction.h"

#include <iostream>

//Basedata Test
#include <mitkGeometryData.h>
#include <mitkPlaneGeometryData.h>
#include <mitkManufacturerLogo.h>
#include <mitkPointSet.h>
#include <mitkImage.h>
#include <mitkSurface.h>

//Mapper Test
#include <mitkPlaneGeometryDataMapper2D.h>
#include <mitkImageVtkMapper2D.h>
#include <mitkSurfaceVtkMapper2D.h>

#include <mitkPlaneGeometryDataVtkMapper3D.h>
#include <mitkPointSetVtkMapper3D.h>
#include <mitkPointSetVtkMapper2D.h>
#include <mitkSurfaceVtkMapper3D.h>
#include <mitkVolumeDataVtkMapper3D.h>

//Interactors
#include <mitkPointSetDataInteractor.h>

//Propertylist Test
#include <mitkImageGenerator.h>

/**
 *  Simple example for a test for the (non-existent) class "DataNode".
 *
 *  argc and argv are the command line parameters which were passed to
 *  the ADD_TEST command in the CMakeLists.txt file. For the automatic
 *  tests, argv is either empty for the simple tests or contains the filename
 *  of a test image for the image tests (see CMakeLists.txt).
 */
class mitkDataNodeTestClass { public:

static void TestDataSetting(mitk::DataNode::Pointer dataNode)
{

  mitk::BaseData::Pointer baseData;

  //NULL pointer Test
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a NULL pointer was set correctly" )

  baseData = mitk::GeometryData::New();
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a GeometryData object was set correctly" )

  baseData = mitk::PlaneGeometryData::New();
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a PlaneGeometryData object was set correctly" )

  baseData = mitk::ManufacturerLogo::New();
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a ManufacturerLogo object was set correctly" )

  baseData = mitk::PointSet::New();
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a PointSet object was set correctly" )

  baseData = mitk::Image::New();
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Image object was set correctly" )

  baseData = mitk::Surface::New();
  dataNode->SetData(baseData);
  MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Surface object was set correctly" )
}
static void TestMapperSetting(mitk::DataNode::Pointer dataNode)
{
  //tests the SetMapper() method
  //in dataNode is a mapper vector which can be accessed by index
  //in this test method we use only slot 0 (filled with null) and slot 1
  //so we also test the destructor of the mapper classes
  mitk::Mapper::Pointer mapper;

  dataNode->SetMapper(0,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(0), "Testing if a NULL pointer was set correctly" )

  mapper = mitk::PlaneGeometryDataMapper2D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PlaneGeometryDataMapper2D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::ImageVtkMapper2D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a ImageVtkMapper2D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::PointSetVtkMapper2D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PointSetVtkMapper2D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::SurfaceVtkMapper2D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SurfaceGLMapper2D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::PlaneGeometryDataVtkMapper3D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PlaneGeometryDataVtkMapper3D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::PointSetVtkMapper3D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PointSetVtkMapper3D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::SurfaceVtkMapper3D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SurfaceVtkMapper3D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )

  mapper = mitk::VolumeDataVtkMapper3D::New();
  dataNode->SetMapper(1,mapper);
  MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a VolumeDataVtkMapper3D was set correctly" )
  MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
}

static void TestInteractorSetting(mitk::DataNode::Pointer dataNode)
{

  //this method tests the SetInteractor() and GetInteractor methods
  //the DataInteractor base class calls the DataNode->SetInteractor method

  mitk::DataInteractor::Pointer interactor;

  MITK_TEST_CONDITION( interactor == dataNode->GetDataInteractor(), "Testing if a NULL pointer was set correctly (DataInteractor)" )

  interactor = mitk::PointSetDataInteractor::New();
  interactor->SetEventConfig("PointSetConfig.xml");
  interactor->SetDataNode(dataNode);
  MITK_TEST_CONDITION( interactor == dataNode->GetDataInteractor(), "Testing if a PointSetDataInteractor was set correctly" )

  interactor = mitk::PointSetDataInteractor::New();
  dataNode->SetDataInteractor(interactor);
  MITK_TEST_CONDITION( interactor == dataNode->GetDataInteractor(), "Testing if a PointSetDataInteractor was set correctly" )
}
static void TestPropertyList(mitk::DataNode::Pointer dataNode)
{

  mitk::PropertyList::Pointer propertyList =  dataNode->GetPropertyList();

  MITK_TEST_CONDITION(dataNode->GetPropertyList() != NULL, "Testing if the constructor set the propertylist" )

  dataNode->SetIntProperty("int", -31337);
  int x;
  dataNode->GetIntProperty("int", x);
  MITK_TEST_CONDITION(x == -31337, "Testing Set/GetIntProperty");

  dataNode->SetBoolProperty("bool", true);
  bool b;
  dataNode->GetBoolProperty("bool", b);
  MITK_TEST_CONDITION(b == true, "Testing Set/GetBoolProperty");
  dataNode->SetFloatProperty("float", -31.337);
  float y;
  dataNode->GetFloatProperty("float", y);
  MITK_TEST_CONDITION(y - -31.337 < 0.01, "Testing Set/GetFloatProperty");
  double yd = 0;
  dataNode->GetDoubleProperty("float", yd);
  MITK_TEST_CONDITION(mitk::Equal(yd, static_cast<double>(y)), "Testing GetDoubleProperty");
  dataNode->SetStringProperty("string", "MITK");
  std::string s = "GANZVIELPLATZ";
  dataNode->GetStringProperty("string", s);
  MITK_TEST_CONDITION(s == "MITK", "Testing Set/GetStringProperty");

  std::string name = "MyTestName";
  dataNode->SetName(name.c_str());
  MITK_TEST_CONDITION(dataNode->GetName() == name, "Testing Set/GetName");
  name = "MySecondTestName";
  dataNode->SetName(name);
  MITK_TEST_CONDITION(dataNode->GetName() == name, "Testing Set/GetName(std::string)");

  MITK_TEST_CONDITION(propertyList == dataNode->GetPropertyList(), "Testing if the propertylist has changed during the last tests" )
}

static void TestSelected(mitk::DataNode::Pointer dataNode)
{
  vtkRenderWindow *renderWindow = vtkRenderWindow::New();

  mitk::VtkPropRenderer::Pointer base = mitk::VtkPropRenderer::New( "the first renderer", renderWindow, mitk::RenderingManager::GetInstance() );

  //with BaseRenderer==Null
  MITK_TEST_CONDITION(!dataNode->IsSelected(), "Testing if this node is not set as selected" )

  dataNode->SetSelected(true);
  MITK_TEST_CONDITION(dataNode->IsSelected(), "Testing if this node is set as selected" )
  dataNode->SetSelected(false);

  dataNode->SetSelected(true,base);

  MITK_TEST_CONDITION(dataNode->IsSelected(base), "Testing if this node with right base renderer is set as selected" )

  //Delete RenderWindow correctly
  renderWindow->Delete();

}
static void TestGetMTime(mitk::DataNode::Pointer dataNode)
{
  unsigned long time;
  time = dataNode->GetMTime();
  mitk::PointSet::Pointer pointSet = mitk::PointSet::New();

  dataNode->SetData(pointSet);
  MITK_TEST_CONDITION( time != dataNode->GetMTime(), "Testing if the node timestamp is updated after adding data to the node" )

  mitk::Point3D point;
  point.Fill(3.0);
  pointSet->SetPoint(0,point);

  //less or equal because dataNode timestamp is little later then the basedata timestamp
  MITK_TEST_CONDITION( pointSet->GetMTime() <= dataNode->GetMTime(), "Testing if the node timestamp is updated after base data was modified" )

  // testing if changing anything in the property list also sets the node in a modified state
  unsigned long lastModified = dataNode->GetMTime();
  dataNode->SetIntProperty("testIntProp", 2344);
  MITK_TEST_CONDITION( lastModified <= dataNode->GetMTime(), "Testing if the node timestamp is updated after property list was modified" )

}
static void TestSetDataUnderPropertyChange()
{
  mitk::Image::Pointer image = mitk::Image::New();
  mitk::Image::Pointer additionalImage = mitk::Image::New();

  mitk::DataNode::Pointer dataNode = mitk::DataNode::New();

  image = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(3u, 3u);

  dataNode->SetData(image);

  float outlineWidth = 0;
  dataNode->GetPropertyValue("outline width", outlineWidth);

  MITK_TEST_CONDITION(mitk::Equal(outlineWidth,1.0), "Testing if the SetData set the default propertylist" )

  dataNode->SetProperty("outline width", mitk::FloatProperty::New( 42.0 ));
  dataNode->SetData(image);
  dataNode->GetPropertyValue("outline width", outlineWidth);

  MITK_TEST_CONDITION(mitk::Equal(outlineWidth,42.0), "Testing if the SetData does not set anything if imagedata is identical" )

  dataNode->SetData(additionalImage);
  dataNode->GetPropertyValue("outline width", outlineWidth);

  MITK_TEST_CONDITION(mitk::Equal(outlineWidth,42.0), "Testing if the SetData does not set the default propertylist if imagedata is already set" )

  mitk::Surface::Pointer surface = mitk::Surface::New();
  dataNode->SetData(surface);

  MITK_TEST_CONDITION(dataNode->GetPropertyValue("outline width", outlineWidth) == false, "Testing if the SetData sets the default propertylist if some new datatype is loaded" )
}
}; //mitkDataNodeTestClass

int mitkDataNodeTest(int /* argc */, char* /*argv*/[])
{
  // always start with this!
  MITK_TEST_BEGIN("DataNode")

  // Global interaction must(!) be initialized
  mitk::GlobalInteraction::GetInstance()->Initialize("global");

  // let's create an object of our class
  mitk::DataNode::Pointer myDataNode = mitk::DataNode::New();

  // first test: did this work?
  // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
  // it makes no sense to continue without an object.
  MITK_TEST_CONDITION_REQUIRED(myDataNode.IsNotNull(),"Testing instantiation")

  //test setData() Method
  mitkDataNodeTestClass::TestDataSetting(myDataNode);
  mitkDataNodeTestClass::TestMapperSetting(myDataNode);
  mitkDataNodeTestClass::TestSetDataUnderPropertyChange();
  //
  //note, that no data is set to the dataNode
  mitkDataNodeTestClass::TestInteractorSetting(myDataNode);
  mitkDataNodeTestClass::TestPropertyList(myDataNode);
  mitkDataNodeTestClass::TestSelected(myDataNode);
  mitkDataNodeTestClass::TestGetMTime(myDataNode);

  // write your own tests here and use the macros from mitkTestingMacros.h !!!
  // do not write to std::cout and do not return from this function yourself!

  // always end with this!
  MITK_TEST_END()
}

<|endoftext|>


<commit_before><commit_msg>fix crash during file format detection, related #i101863#<commit_after><|endoftext|>


<commit_before>//===-- AMDGPUIndirectAddressing.cpp - Indirect Adressing Support ---------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \file
///
/// Instructions can use indirect addressing to index the register file as if it
/// were memory.  This pass lowers RegisterLoad and RegisterStore instructions
/// to either a COPY or a MOV that uses indirect addressing.
//
//===----------------------------------------------------------------------===//

#include "AMDGPU.h"
#include "R600InstrInfo.h"
#include "R600MachineFunctionInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"

using namespace llvm;

namespace {

class AMDGPUIndirectAddressingPass : public MachineFunctionPass {

private:
  static char ID;
  const AMDGPUInstrInfo *TII;

  bool regHasExplicitDef(MachineRegisterInfo &MRI, unsigned Reg) const;

public:
  AMDGPUIndirectAddressingPass(TargetMachine &tm) :
    MachineFunctionPass(ID),
    TII(static_cast<const AMDGPUInstrInfo*>(tm.getInstrInfo()))
    { }

  virtual bool runOnMachineFunction(MachineFunction &MF);

  const char *getPassName() const { return "R600 Handle indirect addressing"; }

};

} // End anonymous namespace

char AMDGPUIndirectAddressingPass::ID = 0;

FunctionPass *llvm::createAMDGPUIndirectAddressingPass(TargetMachine &tm) {
  return new AMDGPUIndirectAddressingPass(tm);
}

bool AMDGPUIndirectAddressingPass::runOnMachineFunction(MachineFunction &MF) {
  MachineRegisterInfo &MRI = MF.getRegInfo();

  int IndirectBegin = TII->getIndirectIndexBegin(MF);
  int IndirectEnd = TII->getIndirectIndexEnd(MF);

  if (IndirectBegin == -1) {
    // No indirect addressing, we can skip this pass
    assert(IndirectEnd == -1);
    return false;
  }

  // The map keeps track of the indirect address that is represented by
  // each virtual register. The key is the register and the value is the
  // indirect address it uses.
  std::map<unsigned, unsigned> RegisterAddressMap;

  // First pass - Lower all of the RegisterStore instructions and track which
  // registers are live.
  for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
                                                      BB != BB_E; ++BB) {
    // This map keeps track of the current live indirect registers.
    // The key is the address and the value is the register
    std::map<unsigned, unsigned> LiveAddressRegisterMap;
    MachineBasicBlock &MBB = *BB;

    for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
                               I != MBB.end(); I = Next) {
      Next = llvm::next(I);
      MachineInstr &MI = *I;

      if (!TII->isRegisterStore(MI)) {
        continue;
      }

      // Lower RegisterStore

      unsigned RegIndex = MI.getOperand(2).getImm();
      unsigned Channel = MI.getOperand(3).getImm();
      unsigned Address = TII->calculateIndirectAddress(RegIndex, Channel);
      const TargetRegisterClass *IndirectStoreRegClass =
                   TII->getIndirectAddrStoreRegClass(MI.getOperand(0).getReg());

      if (MI.getOperand(1).getReg() == AMDGPU::INDIRECT_BASE_ADDR) {
        // Direct register access.
        unsigned DstReg = MRI.createVirtualRegister(IndirectStoreRegClass);

        BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY), DstReg)
                .addOperand(MI.getOperand(0));

        RegisterAddressMap[DstReg] = Address;
        LiveAddressRegisterMap[Address] = DstReg;
      } else {
        // Indirect register access.
        MachineInstrBuilder MOV = TII->buildIndirectWrite(BB, I,
                                           MI.getOperand(0).getReg(), // Value
                                           Address,
                                           MI.getOperand(1).getReg()); // Offset
        for (int i = IndirectBegin; i <= IndirectEnd; ++i) {
          unsigned Addr = TII->calculateIndirectAddress(i, Channel);
          unsigned DstReg = MRI.createVirtualRegister(IndirectStoreRegClass);
          MOV.addReg(DstReg, RegState::Define | RegState::Implicit);
          RegisterAddressMap[DstReg] = Addr;
          LiveAddressRegisterMap[Addr] = DstReg;
        }
      }
      MI.eraseFromParent();
    }

    // Update the live-ins of the succesor blocks
    for (MachineBasicBlock::succ_iterator Succ = MBB.succ_begin(),
                                          SuccEnd = MBB.succ_end();
                                          SuccEnd != Succ; ++Succ) {
      std::map<unsigned, unsigned>::const_iterator Key, KeyEnd;
      for (Key = LiveAddressRegisterMap.begin(),
           KeyEnd = LiveAddressRegisterMap.end(); KeyEnd != Key; ++Key) {
        (*Succ)->addLiveIn(Key->second);
      }
    }
  }

  // Second pass - Lower the RegisterLoad instructions
  for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
                                                      BB != BB_E; ++BB) {
    // Key is the address and the value is the register
    std::map<unsigned, unsigned> LiveAddressRegisterMap;
    MachineBasicBlock &MBB = *BB;

    MachineBasicBlock::livein_iterator LI = MBB.livein_begin();
    while (LI != MBB.livein_end()) {
      std::vector<unsigned> PhiRegisters;

      // Make sure this live in is used for indirect addressing
      if (RegisterAddressMap.find(*LI) == RegisterAddressMap.end()) {
        ++LI;
        continue;
      }

      unsigned Address = RegisterAddressMap[*LI];
      LiveAddressRegisterMap[Address] = *LI;
      PhiRegisters.push_back(*LI);

      // Check if there are other live in registers which map to the same
      // indirect address.
      for (MachineBasicBlock::livein_iterator LJ = llvm::next(LI),
                                              LE = MBB.livein_end();
                                              LJ != LE; ++LJ) {
        unsigned Reg = *LJ;
        if (RegisterAddressMap.find(Reg) == RegisterAddressMap.end()) {
          continue;
        }

        if (RegisterAddressMap[Reg] == Address) {
          PhiRegisters.push_back(Reg);
        }
      }

      if (PhiRegisters.size() == 1) {
        // We don't need to insert a Phi instruction, so we can just add the
        // registers to the live list for the block.
        LiveAddressRegisterMap[Address] = *LI;
        MBB.removeLiveIn(*LI);
      } else {
        // We need to insert a PHI, because we have the same address being
        // written in multiple predecessor blocks.
        const TargetRegisterClass *PhiDstClass =
                   TII->getIndirectAddrStoreRegClass(*(PhiRegisters.begin()));
        unsigned PhiDstReg = MRI.createVirtualRegister(PhiDstClass);
        MachineInstrBuilder Phi = BuildMI(MBB, MBB.begin(),
                                          MBB.findDebugLoc(MBB.begin()),
                                          TII->get(AMDGPU::PHI), PhiDstReg);

        for (std::vector<unsigned>::const_iterator RI = PhiRegisters.begin(),
                                                   RE = PhiRegisters.end();
                                                   RI != RE; ++RI) {
          unsigned Reg = *RI;
          MachineInstr *DefInst = MRI.getVRegDef(Reg);
          assert(DefInst);
          MachineBasicBlock *RegBlock = DefInst->getParent();
          Phi.addReg(Reg);
          Phi.addMBB(RegBlock);
          MBB.removeLiveIn(Reg);
        }
        RegisterAddressMap[PhiDstReg] = Address;
        LiveAddressRegisterMap[Address] = PhiDstReg;
      }
      LI = MBB.livein_begin();
    }

    for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
                               I != MBB.end(); I = Next) {
      Next = llvm::next(I);
      MachineInstr &MI = *I;

      if (!TII->isRegisterLoad(MI)) {
        if (MI.getOpcode() == AMDGPU::PHI) {
          continue;
        }
        // Check for indirect register defs
        for (unsigned OpIdx = 0, NumOperands = MI.getNumOperands();
                                 OpIdx < NumOperands; ++OpIdx) {
          MachineOperand &MO = MI.getOperand(OpIdx);
          if (MO.isReg() && MO.isDef() &&
              RegisterAddressMap.find(MO.getReg()) != RegisterAddressMap.end()) {
            unsigned Reg = MO.getReg();
            unsigned LiveAddress = RegisterAddressMap[Reg];
            // Chain the live-ins
            if (LiveAddressRegisterMap.find(LiveAddress) !=
                                                     RegisterAddressMap.end()) {
              MI.addOperand(MachineOperand::CreateReg(
                                  LiveAddressRegisterMap[LiveAddress],
                                  false, // isDef
                                  true,  // isImp
                                  true));  // isKill
            }
            LiveAddressRegisterMap[LiveAddress] = Reg;
          }
        }
        continue;
      }

      const TargetRegisterClass *SuperIndirectRegClass =
                                                TII->getSuperIndirectRegClass();
      const TargetRegisterClass *IndirectLoadRegClass =
                                             TII->getIndirectAddrLoadRegClass();
      unsigned IndirectReg = MRI.createVirtualRegister(SuperIndirectRegClass);

      unsigned RegIndex = MI.getOperand(2).getImm();
      unsigned Channel = MI.getOperand(3).getImm();
      unsigned Address = TII->calculateIndirectAddress(RegIndex, Channel);

      if (MI.getOperand(1).getReg() == AMDGPU::INDIRECT_BASE_ADDR) {
        // Direct register access
        unsigned Reg = LiveAddressRegisterMap[Address];
        unsigned AddrReg = IndirectLoadRegClass->getRegister(Address);

        if (regHasExplicitDef(MRI, Reg)) {
          // If the register we are reading from has an explicit def, then that
          // means it was written via a direct register access (i.e. COPY
          // or other instruction that doesn't use indirect addressing).  In
          // this case we know where the value has been stored, so we can just
          // issue a copy.
          BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY),
                  MI.getOperand(0).getReg())
                  .addReg(Reg);
        } else {
          // If the register we are reading has an implicit def, then that
          // means it was written by an indirect register access (i.e. An
          // instruction that uses indirect addressing.
          BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY),
                   MI.getOperand(0).getReg())
                   .addReg(AddrReg)
                   .addReg(Reg, RegState::Implicit);
        }
      } else {
        // Indirect register access

        // Note on REQ_SEQUENCE instructons: You can't actually use the register
        // it defines unless  you have an instruction that takes the defined
        // register class as an operand.

        MachineInstrBuilder Sequence = BuildMI(MBB, I, MBB.findDebugLoc(I),
                                               TII->get(AMDGPU::REG_SEQUENCE),
                                               IndirectReg);
        for (int i = IndirectBegin; i <= IndirectEnd; ++i) {
          unsigned Addr = TII->calculateIndirectAddress(i, Channel);
          if (LiveAddressRegisterMap.find(Addr) == LiveAddressRegisterMap.end()) {
            continue;
          }
          unsigned Reg = LiveAddressRegisterMap[Addr];

          // We only need to use REG_SEQUENCE for explicit defs, since the
          // register coalescer won't do anything with the implicit defs.
          if (!regHasExplicitDef(MRI, Reg)) {
            continue;
          }

          // Insert a REQ_SEQUENCE instruction to force the register allocator
          // to allocate the virtual register to the correct physical register.
          Sequence.addReg(LiveAddressRegisterMap[Addr]);
          Sequence.addImm(TII->getRegisterInfo().getIndirectSubReg(Addr));
        }
        MachineInstrBuilder Mov = TII->buildIndirectRead(BB, I,
                                           MI.getOperand(0).getReg(), // Value
                                           Address,
                                           MI.getOperand(1).getReg()); // Offset

        Mov.addReg(IndirectReg, RegState::Implicit | RegState::Kill);
        Mov.addReg(LiveAddressRegisterMap[Address], RegState::Implicit);

      }
      MI.eraseFromParent();
    }
  }
  return false;
}

bool AMDGPUIndirectAddressingPass::regHasExplicitDef(MachineRegisterInfo &MRI,
                                                  unsigned Reg) const {
  MachineInstr *DefInstr = MRI.getVRegDef(Reg);

  if (!DefInstr) {
    return false;
  }

  if (DefInstr->getOpcode() == AMDGPU::PHI) {
    bool Explicit = false;
    for (MachineInstr::const_mop_iterator I = DefInstr->operands_begin(),
                                          E = DefInstr->operands_end();
                                          I != E; ++I) {
      const MachineOperand &MO = *I;
      if (!MO.isReg() || MO.isDef()) {
        continue;
      }

      Explicit = Explicit || regHasExplicitDef(MRI, MO.getReg());
    }
    return Explicit;
  }

  return DefInstr->getOperand(0).isReg() &&
         DefInstr->getOperand(0).getReg() == Reg;
}
<commit_msg>R600: Don't compare iterators of different maps.<commit_after>//===-- AMDGPUIndirectAddressing.cpp - Indirect Adressing Support ---------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \file
///
/// Instructions can use indirect addressing to index the register file as if it
/// were memory.  This pass lowers RegisterLoad and RegisterStore instructions
/// to either a COPY or a MOV that uses indirect addressing.
//
//===----------------------------------------------------------------------===//

#include "AMDGPU.h"
#include "R600InstrInfo.h"
#include "R600MachineFunctionInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"

using namespace llvm;

namespace {

class AMDGPUIndirectAddressingPass : public MachineFunctionPass {

private:
  static char ID;
  const AMDGPUInstrInfo *TII;

  bool regHasExplicitDef(MachineRegisterInfo &MRI, unsigned Reg) const;

public:
  AMDGPUIndirectAddressingPass(TargetMachine &tm) :
    MachineFunctionPass(ID),
    TII(static_cast<const AMDGPUInstrInfo*>(tm.getInstrInfo()))
    { }

  virtual bool runOnMachineFunction(MachineFunction &MF);

  const char *getPassName() const { return "R600 Handle indirect addressing"; }

};

} // End anonymous namespace

char AMDGPUIndirectAddressingPass::ID = 0;

FunctionPass *llvm::createAMDGPUIndirectAddressingPass(TargetMachine &tm) {
  return new AMDGPUIndirectAddressingPass(tm);
}

bool AMDGPUIndirectAddressingPass::runOnMachineFunction(MachineFunction &MF) {
  MachineRegisterInfo &MRI = MF.getRegInfo();

  int IndirectBegin = TII->getIndirectIndexBegin(MF);
  int IndirectEnd = TII->getIndirectIndexEnd(MF);

  if (IndirectBegin == -1) {
    // No indirect addressing, we can skip this pass
    assert(IndirectEnd == -1);
    return false;
  }

  // The map keeps track of the indirect address that is represented by
  // each virtual register. The key is the register and the value is the
  // indirect address it uses.
  std::map<unsigned, unsigned> RegisterAddressMap;

  // First pass - Lower all of the RegisterStore instructions and track which
  // registers are live.
  for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
                                                      BB != BB_E; ++BB) {
    // This map keeps track of the current live indirect registers.
    // The key is the address and the value is the register
    std::map<unsigned, unsigned> LiveAddressRegisterMap;
    MachineBasicBlock &MBB = *BB;

    for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
                               I != MBB.end(); I = Next) {
      Next = llvm::next(I);
      MachineInstr &MI = *I;

      if (!TII->isRegisterStore(MI)) {
        continue;
      }

      // Lower RegisterStore

      unsigned RegIndex = MI.getOperand(2).getImm();
      unsigned Channel = MI.getOperand(3).getImm();
      unsigned Address = TII->calculateIndirectAddress(RegIndex, Channel);
      const TargetRegisterClass *IndirectStoreRegClass =
                   TII->getIndirectAddrStoreRegClass(MI.getOperand(0).getReg());

      if (MI.getOperand(1).getReg() == AMDGPU::INDIRECT_BASE_ADDR) {
        // Direct register access.
        unsigned DstReg = MRI.createVirtualRegister(IndirectStoreRegClass);

        BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY), DstReg)
                .addOperand(MI.getOperand(0));

        RegisterAddressMap[DstReg] = Address;
        LiveAddressRegisterMap[Address] = DstReg;
      } else {
        // Indirect register access.
        MachineInstrBuilder MOV = TII->buildIndirectWrite(BB, I,
                                           MI.getOperand(0).getReg(), // Value
                                           Address,
                                           MI.getOperand(1).getReg()); // Offset
        for (int i = IndirectBegin; i <= IndirectEnd; ++i) {
          unsigned Addr = TII->calculateIndirectAddress(i, Channel);
          unsigned DstReg = MRI.createVirtualRegister(IndirectStoreRegClass);
          MOV.addReg(DstReg, RegState::Define | RegState::Implicit);
          RegisterAddressMap[DstReg] = Addr;
          LiveAddressRegisterMap[Addr] = DstReg;
        }
      }
      MI.eraseFromParent();
    }

    // Update the live-ins of the succesor blocks
    for (MachineBasicBlock::succ_iterator Succ = MBB.succ_begin(),
                                          SuccEnd = MBB.succ_end();
                                          SuccEnd != Succ; ++Succ) {
      std::map<unsigned, unsigned>::const_iterator Key, KeyEnd;
      for (Key = LiveAddressRegisterMap.begin(),
           KeyEnd = LiveAddressRegisterMap.end(); KeyEnd != Key; ++Key) {
        (*Succ)->addLiveIn(Key->second);
      }
    }
  }

  // Second pass - Lower the RegisterLoad instructions
  for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
                                                      BB != BB_E; ++BB) {
    // Key is the address and the value is the register
    std::map<unsigned, unsigned> LiveAddressRegisterMap;
    MachineBasicBlock &MBB = *BB;

    MachineBasicBlock::livein_iterator LI = MBB.livein_begin();
    while (LI != MBB.livein_end()) {
      std::vector<unsigned> PhiRegisters;

      // Make sure this live in is used for indirect addressing
      if (RegisterAddressMap.find(*LI) == RegisterAddressMap.end()) {
        ++LI;
        continue;
      }

      unsigned Address = RegisterAddressMap[*LI];
      LiveAddressRegisterMap[Address] = *LI;
      PhiRegisters.push_back(*LI);

      // Check if there are other live in registers which map to the same
      // indirect address.
      for (MachineBasicBlock::livein_iterator LJ = llvm::next(LI),
                                              LE = MBB.livein_end();
                                              LJ != LE; ++LJ) {
        unsigned Reg = *LJ;
        if (RegisterAddressMap.find(Reg) == RegisterAddressMap.end()) {
          continue;
        }

        if (RegisterAddressMap[Reg] == Address) {
          PhiRegisters.push_back(Reg);
        }
      }

      if (PhiRegisters.size() == 1) {
        // We don't need to insert a Phi instruction, so we can just add the
        // registers to the live list for the block.
        LiveAddressRegisterMap[Address] = *LI;
        MBB.removeLiveIn(*LI);
      } else {
        // We need to insert a PHI, because we have the same address being
        // written in multiple predecessor blocks.
        const TargetRegisterClass *PhiDstClass =
                   TII->getIndirectAddrStoreRegClass(*(PhiRegisters.begin()));
        unsigned PhiDstReg = MRI.createVirtualRegister(PhiDstClass);
        MachineInstrBuilder Phi = BuildMI(MBB, MBB.begin(),
                                          MBB.findDebugLoc(MBB.begin()),
                                          TII->get(AMDGPU::PHI), PhiDstReg);

        for (std::vector<unsigned>::const_iterator RI = PhiRegisters.begin(),
                                                   RE = PhiRegisters.end();
                                                   RI != RE; ++RI) {
          unsigned Reg = *RI;
          MachineInstr *DefInst = MRI.getVRegDef(Reg);
          assert(DefInst);
          MachineBasicBlock *RegBlock = DefInst->getParent();
          Phi.addReg(Reg);
          Phi.addMBB(RegBlock);
          MBB.removeLiveIn(Reg);
        }
        RegisterAddressMap[PhiDstReg] = Address;
        LiveAddressRegisterMap[Address] = PhiDstReg;
      }
      LI = MBB.livein_begin();
    }

    for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
                               I != MBB.end(); I = Next) {
      Next = llvm::next(I);
      MachineInstr &MI = *I;

      if (!TII->isRegisterLoad(MI)) {
        if (MI.getOpcode() == AMDGPU::PHI) {
          continue;
        }
        // Check for indirect register defs
        for (unsigned OpIdx = 0, NumOperands = MI.getNumOperands();
                                 OpIdx < NumOperands; ++OpIdx) {
          MachineOperand &MO = MI.getOperand(OpIdx);
          if (MO.isReg() && MO.isDef() &&
              RegisterAddressMap.find(MO.getReg()) != RegisterAddressMap.end()) {
            unsigned Reg = MO.getReg();
            unsigned LiveAddress = RegisterAddressMap[Reg];
            // Chain the live-ins
            if (LiveAddressRegisterMap.find(LiveAddress) !=
                LiveAddressRegisterMap.end()) {
              MI.addOperand(MachineOperand::CreateReg(
                                  LiveAddressRegisterMap[LiveAddress],
                                  false, // isDef
                                  true,  // isImp
                                  true));  // isKill
            }
            LiveAddressRegisterMap[LiveAddress] = Reg;
          }
        }
        continue;
      }

      const TargetRegisterClass *SuperIndirectRegClass =
                                                TII->getSuperIndirectRegClass();
      const TargetRegisterClass *IndirectLoadRegClass =
                                             TII->getIndirectAddrLoadRegClass();
      unsigned IndirectReg = MRI.createVirtualRegister(SuperIndirectRegClass);

      unsigned RegIndex = MI.getOperand(2).getImm();
      unsigned Channel = MI.getOperand(3).getImm();
      unsigned Address = TII->calculateIndirectAddress(RegIndex, Channel);

      if (MI.getOperand(1).getReg() == AMDGPU::INDIRECT_BASE_ADDR) {
        // Direct register access
        unsigned Reg = LiveAddressRegisterMap[Address];
        unsigned AddrReg = IndirectLoadRegClass->getRegister(Address);

        if (regHasExplicitDef(MRI, Reg)) {
          // If the register we are reading from has an explicit def, then that
          // means it was written via a direct register access (i.e. COPY
          // or other instruction that doesn't use indirect addressing).  In
          // this case we know where the value has been stored, so we can just
          // issue a copy.
          BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY),
                  MI.getOperand(0).getReg())
                  .addReg(Reg);
        } else {
          // If the register we are reading has an implicit def, then that
          // means it was written by an indirect register access (i.e. An
          // instruction that uses indirect addressing.
          BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY),
                   MI.getOperand(0).getReg())
                   .addReg(AddrReg)
                   .addReg(Reg, RegState::Implicit);
        }
      } else {
        // Indirect register access

        // Note on REQ_SEQUENCE instructons: You can't actually use the register
        // it defines unless  you have an instruction that takes the defined
        // register class as an operand.

        MachineInstrBuilder Sequence = BuildMI(MBB, I, MBB.findDebugLoc(I),
                                               TII->get(AMDGPU::REG_SEQUENCE),
                                               IndirectReg);
        for (int i = IndirectBegin; i <= IndirectEnd; ++i) {
          unsigned Addr = TII->calculateIndirectAddress(i, Channel);
          if (LiveAddressRegisterMap.find(Addr) == LiveAddressRegisterMap.end()) {
            continue;
          }
          unsigned Reg = LiveAddressRegisterMap[Addr];

          // We only need to use REG_SEQUENCE for explicit defs, since the
          // register coalescer won't do anything with the implicit defs.
          if (!regHasExplicitDef(MRI, Reg)) {
            continue;
          }

          // Insert a REQ_SEQUENCE instruction to force the register allocator
          // to allocate the virtual register to the correct physical register.
          Sequence.addReg(LiveAddressRegisterMap[Addr]);
          Sequence.addImm(TII->getRegisterInfo().getIndirectSubReg(Addr));
        }
        MachineInstrBuilder Mov = TII->buildIndirectRead(BB, I,
                                           MI.getOperand(0).getReg(), // Value
                                           Address,
                                           MI.getOperand(1).getReg()); // Offset

        Mov.addReg(IndirectReg, RegState::Implicit | RegState::Kill);
        Mov.addReg(LiveAddressRegisterMap[Address], RegState::Implicit);

      }
      MI.eraseFromParent();
    }
  }
  return false;
}

bool AMDGPUIndirectAddressingPass::regHasExplicitDef(MachineRegisterInfo &MRI,
                                                  unsigned Reg) const {
  MachineInstr *DefInstr = MRI.getVRegDef(Reg);

  if (!DefInstr) {
    return false;
  }

  if (DefInstr->getOpcode() == AMDGPU::PHI) {
    bool Explicit = false;
    for (MachineInstr::const_mop_iterator I = DefInstr->operands_begin(),
                                          E = DefInstr->operands_end();
                                          I != E; ++I) {
      const MachineOperand &MO = *I;
      if (!MO.isReg() || MO.isDef()) {
        continue;
      }

      Explicit = Explicit || regHasExplicitDef(MRI, MO.getReg());
    }
    return Explicit;
  }

  return DefInstr->getOperand(0).isReg() &&
         DefInstr->getOperand(0).getReg() == Reg;
}
<|endoftext|>


<commit_before>//===-- X86MCAsmInfo.cpp - X86 asm properties -----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declarations of the X86MCAsmInfo properties.
//
//===----------------------------------------------------------------------===//

#include "X86MCAsmInfo.h"
#include "X86TargetMachine.h"
#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ELF.h"
using namespace llvm;

enum AsmWriterFlavorTy {
  // Note: This numbering has to match the GCC assembler dialects for inline
  // asm alternatives to work right.
  ATT = 0, Intel = 1
};

static cl::opt<AsmWriterFlavorTy>
AsmWriterFlavor("x86-asm-syntax", cl::init(ATT),
  cl::desc("Choose style of code to emit from X86 backend:"),
  cl::values(clEnumValN(ATT,   "att",   "Emit AT&T-style assembly"),
             clEnumValN(Intel, "intel", "Emit Intel-style assembly"),
             clEnumValEnd));

static const char *const x86_asm_table[] = {
  "{si}", "S",
  "{di}", "D",
  "{ax}", "a",
  "{cx}", "c",
  "{memory}", "memory",
  "{flags}", "",
  "{dirflag}", "",
  "{fpsr}", "",
  "{fpcr}", "",
  "{cc}", "cc",
  0,0};

X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T) {
  bool is64Bit = T.getArch() == Triple::x86_64;
  if (is64Bit)
    PointerSize = 8;

  AsmTransCBE = x86_asm_table;
  AssemblerDialect = AsmWriterFlavor;

  TextAlignFillValue = 0x90;

  if (!is64Bit)
    Data64bitsDirective = 0;       // we can't emit a 64-bit unit

  // Use ## as a comment string so that .s files generated by llvm can go
  // through the GCC preprocessor without causing an error.  This is needed
  // because "clang foo.s" runs the C preprocessor, which is usually reserved
  // for .S files on other systems.  Perhaps this is because the file system
  // wasn't always case preserving or something.
  CommentString = "##";
  PCSymbol = ".";

  SupportsDebugInformation = true;
  DwarfUsesInlineInfoSection = true;

  // Exceptions handling
  ExceptionsType = ExceptionHandling::DwarfCFI;
}

X86_64MCAsmInfoDarwin::X86_64MCAsmInfoDarwin(const Triple &Triple)
  : X86MCAsmInfoDarwin(Triple) {
}

X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &T) {
  if (T.getArch() == Triple::x86_64)
    PointerSize = 8;

  AsmTransCBE = x86_asm_table;
  AssemblerDialect = AsmWriterFlavor;

  TextAlignFillValue = 0x90;

  PrivateGlobalPrefix = ".L";
  WeakRefDirective = "\t.weak\t";
  PCSymbol = ".";

  // Set up DWARF directives
  HasLEB128 = true;  // Target asm supports leb128 directives (little-endian)

  // Debug Information
  SupportsDebugInformation = true;

  // Exceptions handling
  ExceptionsType = ExceptionHandling::DwarfCFI;

  // OpenBSD has buggy support for .quad in 32-bit mode, just split into two
  // .words.
  if (T.getOS() == Triple::OpenBSD && T.getArch() == Triple::x86)
    Data64bitsDirective = 0;
}

const MCExpr *
X86_64MCAsmInfoDarwin::getExprForPersonalitySymbol(const MCSymbol *Sym,
                                                   unsigned Encoding,
                                                   MCStreamer &Streamer) const {
  MCContext &Context = Streamer.getContext();
  const MCExpr *Res =
    MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTPCREL, Context);
  const MCExpr *Four = MCConstantExpr::Create(4, Context);
  return MCBinaryExpr::CreateAdd(Res, Four, Context);
}

const MCSection *X86ELFMCAsmInfo::
getNonexecutableStackSection(MCContext &Ctx) const {
  return Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS,
                           0, SectionKind::getMetadata());
}

X86MCAsmInfoCOFF::X86MCAsmInfoCOFF(const Triple &Triple) {
  if (Triple.getArch() == Triple::x86_64) {
    GlobalPrefix = "";
    PrivateGlobalPrefix = ".L";
  }

  AsmTransCBE = x86_asm_table;
  AssemblerDialect = AsmWriterFlavor;

  TextAlignFillValue = 0x90;
}
<commit_msg>Remove an unnecessary header from this file. I don't think this header was really intended, and it may have been required prior to some of the recent refactors. Including it however causes LLVMX86Desc to need symbols from LLVMX86CodeGen, forming a dependency cycle. This was masked in almost all builds: Clang, and GCC w/ optimizations didn't actually emit the symbols!<commit_after>//===-- X86MCAsmInfo.cpp - X86 asm properties -----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declarations of the X86MCAsmInfo properties.
//
//===----------------------------------------------------------------------===//

#include "X86MCAsmInfo.h"
#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ELF.h"
using namespace llvm;

enum AsmWriterFlavorTy {
  // Note: This numbering has to match the GCC assembler dialects for inline
  // asm alternatives to work right.
  ATT = 0, Intel = 1
};

static cl::opt<AsmWriterFlavorTy>
AsmWriterFlavor("x86-asm-syntax", cl::init(ATT),
  cl::desc("Choose style of code to emit from X86 backend:"),
  cl::values(clEnumValN(ATT,   "att",   "Emit AT&T-style assembly"),
             clEnumValN(Intel, "intel", "Emit Intel-style assembly"),
             clEnumValEnd));

static const char *const x86_asm_table[] = {
  "{si}", "S",
  "{di}", "D",
  "{ax}", "a",
  "{cx}", "c",
  "{memory}", "memory",
  "{flags}", "",
  "{dirflag}", "",
  "{fpsr}", "",
  "{fpcr}", "",
  "{cc}", "cc",
  0,0};

X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T) {
  bool is64Bit = T.getArch() == Triple::x86_64;
  if (is64Bit)
    PointerSize = 8;

  AsmTransCBE = x86_asm_table;
  AssemblerDialect = AsmWriterFlavor;

  TextAlignFillValue = 0x90;

  if (!is64Bit)
    Data64bitsDirective = 0;       // we can't emit a 64-bit unit

  // Use ## as a comment string so that .s files generated by llvm can go
  // through the GCC preprocessor without causing an error.  This is needed
  // because "clang foo.s" runs the C preprocessor, which is usually reserved
  // for .S files on other systems.  Perhaps this is because the file system
  // wasn't always case preserving or something.
  CommentString = "##";
  PCSymbol = ".";

  SupportsDebugInformation = true;
  DwarfUsesInlineInfoSection = true;

  // Exceptions handling
  ExceptionsType = ExceptionHandling::DwarfCFI;
}

X86_64MCAsmInfoDarwin::X86_64MCAsmInfoDarwin(const Triple &Triple)
  : X86MCAsmInfoDarwin(Triple) {
}

X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &T) {
  if (T.getArch() == Triple::x86_64)
    PointerSize = 8;

  AsmTransCBE = x86_asm_table;
  AssemblerDialect = AsmWriterFlavor;

  TextAlignFillValue = 0x90;

  PrivateGlobalPrefix = ".L";
  WeakRefDirective = "\t.weak\t";
  PCSymbol = ".";

  // Set up DWARF directives
  HasLEB128 = true;  // Target asm supports leb128 directives (little-endian)

  // Debug Information
  SupportsDebugInformation = true;

  // Exceptions handling
  ExceptionsType = ExceptionHandling::DwarfCFI;

  // OpenBSD has buggy support for .quad in 32-bit mode, just split into two
  // .words.
  if (T.getOS() == Triple::OpenBSD && T.getArch() == Triple::x86)
    Data64bitsDirective = 0;
}

const MCExpr *
X86_64MCAsmInfoDarwin::getExprForPersonalitySymbol(const MCSymbol *Sym,
                                                   unsigned Encoding,
                                                   MCStreamer &Streamer) const {
  MCContext &Context = Streamer.getContext();
  const MCExpr *Res =
    MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTPCREL, Context);
  const MCExpr *Four = MCConstantExpr::Create(4, Context);
  return MCBinaryExpr::CreateAdd(Res, Four, Context);
}

const MCSection *X86ELFMCAsmInfo::
getNonexecutableStackSection(MCContext &Ctx) const {
  return Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS,
                           0, SectionKind::getMetadata());
}

X86MCAsmInfoCOFF::X86MCAsmInfoCOFF(const Triple &Triple) {
  if (Triple.getArch() == Triple::x86_64) {
    GlobalPrefix = "";
    PrivateGlobalPrefix = ".L";
  }

  AsmTransCBE = x86_asm_table;
  AssemblerDialect = AsmWriterFlavor;

  TextAlignFillValue = 0x90;
}
<|endoftext|>


<commit_before>/*
There are N gas stations along a circular route, where the amount of gas at station i is gas[i].

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.

Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.

Note:
The solution is guaranteed to be unique.
*/

#include <vector>
#include <iostream>

class Solution {
public:
    int canCompleteCircuit(std::vector<int>& gas, std::vector<int>& cost) {
        size_t len = gas.size();
        int diff = 0;
        int start = 0;
        int sum = 0;
        for (int i = 0; i < len; ++i) {
            diff += gas[i] - cost[i];
            if (sum < 0) {
                start = i;
                sum = gas[i] - cost[i];
            } else {
                sum += gas[i] + cost[i];
            }
        }
        return diff < 0 ? -1 : start;
    }
};

<commit_msg>Update GasStation.cpp<commit_after>/*
There are N gas stations along a circular route, where the amount of gas at station i is gas[i].

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.

Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.

Note:
The solution is guaranteed to be unique.
*/

#include <vector>
#include <iostream>

class Solution {
public:
    int canCompleteCircuit(std::vector<int>& gas, std::vector<int>& cost) {
        size_t len = gas.size();
        int diff = 0;
        int start = 0;
        int sum = 0;
        for (int i = 0; i < len; ++i) {
            diff += gas[i] - cost[i];
            if (sum < 0) {
                start = i;
                sum = gas[i] - cost[i];
            } else {
                sum += gas[i] - cost[i];
            }
        }
        return diff < 0 ? -1 : start;
    }
};

<|endoftext|>


<commit_before>/*
 * opencog/atoms/reduct/FoldLink.cc
 *
 * Copyright (C) 2015 Linas Vepstas
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Fold Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Fold Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <limits>

#include <opencog/atomspace/atom_types.h>
#include <opencog/atomspace/ClassServer.h>
#include <opencog/atoms/NumberNode.h>
#include "FoldLink.h"

using namespace opencog;

FoldLink::FoldLink(const HandleSeq& oset,
                   TruthValuePtr tv,
                   AttentionValuePtr av)
    : FunctionLink(FOLD_LINK, oset, tv, av)
{
	init();
}

FoldLink::FoldLink(Type t, const HandleSeq& oset,
                   TruthValuePtr tv,
                   AttentionValuePtr av)
    : FunctionLink(t, oset, tv, av)
{
	if (not classserver().isA(t, FOLD_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a FoldLink");
	init();
}

FoldLink::FoldLink(Type t, const Handle& a, const Handle& b,
                   TruthValuePtr tv,
                   AttentionValuePtr av)
    : FunctionLink(t, a, b, tv, av)
{
	if (not classserver().isA(t, FOLD_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a FoldLink");
	init();
}

FoldLink::FoldLink(Link& l)
    : FunctionLink(l)
{
	Type tscope = l.getType();
	if (not classserver().isA(tscope, FOLD_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a FoldLink");
	init();
}

void FoldLink::init(void)
{
	knil = std::numeric_limits<double>::quiet_NaN();
	kons = NULL;
}

/// reduce() -- reduce the expression by summing constants, etc.
///
/// No actual black-box evaluation or execution is performed. Only
/// clearbox reductions are performed.
///
/// Examples: the reduct of (FoldLink (NumberNode 2) (NumberNode 2))
/// is (NumberNode 4) -- its just a constant.
///
/// The reduct of (FoldLink (VariableNode "$x") (NumberNode 0)) is
/// (VariableNode "$x"), because adding zero to anything yeilds the
/// thing itself.
Handle FoldLink::reduce(void)
{
	// Assume that the expression is a mixture of constants and variables.
	// Sum the constants, and eliminate the nils.
	HandleSeq reduct;
	bool did_reduce = false;
	double sum = knil;
	for (const Handle& h: _outgoing)
	{
		Type t = h->getType();
		if (NUMBER_NODE != t and
		    VARIABLE_NODE != t and
		    (not classserver().isA(t, FUNCTION_LINK))
		)
			throw RuntimeException(TRACE_INFO,
				"Don't know how to reduce %s", h->toShortString().c_str());

		Handle redh(h);
		if (classserver().isA(t, FUNCTION_LINK))
		{
			FunctionLinkPtr fff(FunctionLinkCast(h));
			if (NULL == fff)
				fff = createFunctionLink(*LinkCast(h));

			redh = fff->reduce();
			t = redh->getType();
		}

		if (h != redh) did_reduce = true;

		if (NUMBER_NODE == t)
		{
			NumberNodePtr nnn(NumberNodeCast(redh));
			if (NULL == nnn)
				nnn = createNumberNode(*NodeCast(redh));
			sum = kons(sum, nnn->getValue());
			did_reduce = true;
			continue;
		}
		reduct.push_back(redh);
	}

	// If nothing reduced, nothing to do.
	if (not did_reduce) return getHandle();

	// If it reduced to just one number:
	if (0 == reduct.size())
		return Handle(createNumberNode(sum));

	// If it didn't sum to nil, then we have to keep it.
	if (knil != sum)
		reduct.push_back(Handle(createNumberNode(sum)));

	// If it reduced to just one thing:
	if (1 == reduct.size()) return reduct[0];

	Handle result(createLink(getType(), reduct));

	// Place the result into the same atomspace we are in.
	if (_atomTable)
	{
		AtomSpace* as = _atomTable->getAtomSpace();
		return as->addAtom(result);
	}

	return result;
}

// ===========================================================

/// execute() -- Execute the expression, returning a number
///
/// Similar to reduce(), above, except that this can only work
/// on fully grounded (closed) sentences: after executation,
/// everything must be a number, and there can be no variables
/// in sight.
static inline double get_double(AtomSpace *as, Handle h)
{
	// Recurse, and execute anything below...
	FunctionLinkPtr flp(FunctionLinkCast(h));
	if (flp)
		h = flp->execute(as);

	NumberNodePtr nnn(NumberNodeCast(h));
	if (nnn == NULL)
		throw RuntimeException(TRACE_INFO,
			  "Expecting a NumberNode, got %s",
		     classserver().getTypeName(h->getType()).c_str());

	return nnn->getValue();
}

Handle FoldLink::execute(AtomSpace* as) const
{
	double sum = knil;
	for (Handle h: _outgoing)
	{
		sum = kons(sum, get_double(as, h));
	}

	if (as) return as->addAtom(createNumberNode(sum));
	return Handle(createNumberNode(sum));
}
<commit_msg>Bug fix<commit_after>/*
 * opencog/atoms/reduct/FoldLink.cc
 *
 * Copyright (C) 2015 Linas Vepstas
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Fold Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Fold Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <limits>

#include <opencog/atomspace/atom_types.h>
#include <opencog/atomspace/ClassServer.h>
#include <opencog/atoms/NumberNode.h>
#include "FoldLink.h"

using namespace opencog;

FoldLink::FoldLink(const HandleSeq& oset,
                   TruthValuePtr tv,
                   AttentionValuePtr av)
    : FunctionLink(FOLD_LINK, oset, tv, av)
{
	init();
}

FoldLink::FoldLink(Type t, const HandleSeq& oset,
                   TruthValuePtr tv,
                   AttentionValuePtr av)
    : FunctionLink(t, oset, tv, av)
{
	if (not classserver().isA(t, FOLD_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a FoldLink");
	init();
}

FoldLink::FoldLink(Type t, const Handle& a, const Handle& b,
                   TruthValuePtr tv,
                   AttentionValuePtr av)
    : FunctionLink(t, a, b, tv, av)
{
	if (not classserver().isA(t, FOLD_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a FoldLink");
	init();
}

FoldLink::FoldLink(Link& l)
    : FunctionLink(l)
{
	Type tscope = l.getType();
	if (not classserver().isA(tscope, FOLD_LINK))
		throw InvalidParamException(TRACE_INFO, "Expecting a FoldLink");
	init();
}

void FoldLink::init(void)
{
	knil = std::numeric_limits<double>::quiet_NaN();
	kons = NULL;
}

/// reduce() -- reduce the expression by summing constants, etc.
///
/// No actual black-box evaluation or execution is performed. Only
/// clearbox reductions are performed.
///
/// Examples: the reduct of (FoldLink (NumberNode 2) (NumberNode 2))
/// is (NumberNode 4) -- its just a constant.
///
/// The reduct of (FoldLink (VariableNode "$x") (NumberNode 0)) is
/// (VariableNode "$x"), because adding zero to anything yeilds the
/// thing itself.
Handle FoldLink::reduce(void)
{
	// Assume that the expression is a mixture of constants and variables.
	// Sum the constants, and eliminate the nils.
	HandleSeq reduct;
	bool did_reduce = false;
	double sum = knil;
	for (const Handle& h: _outgoing)
	{
		Type t = h->getType();
		if (NUMBER_NODE != t and
		    VARIABLE_NODE != t and
		    (not classserver().isA(t, FUNCTION_LINK))
		)
			throw RuntimeException(TRACE_INFO,
				"Don't know how to reduce %s", h->toShortString().c_str());

		Handle redh(h);
		if (classserver().isA(t, FUNCTION_LINK))
		{
			FunctionLinkPtr fff(FunctionLinkCast(h));
			if (NULL == fff)
				fff = createFunctionLink(*LinkCast(h));

			redh = fff->reduce();
			t = redh->getType();
		}

		if (h != redh) did_reduce = true;

		if (NUMBER_NODE == t)
		{
			NumberNodePtr nnn(NumberNodeCast(redh));
			if (NULL == nnn)
				nnn = createNumberNode(*NodeCast(redh));
			sum = kons(sum, nnn->getValue());
			did_reduce = true;
			continue;
		}
		reduct.push_back(redh);
	}

	// If nothing reduced, nothing to do.
	if (not did_reduce)
	{
		if (1 == _outgoing.size())
			return _outgoing[0];
		return getHandle();
	}

	// If it reduced to just one number:
	if (0 == reduct.size())
		return Handle(createNumberNode(sum));

	// If it didn't sum to nil, then we have to keep it.
	if (knil != sum)
		reduct.push_back(Handle(createNumberNode(sum)));

	// If it reduced to just one thing:
	if (1 == reduct.size()) return reduct[0];

	Handle result(createLink(getType(), reduct));

	// Place the result into the same atomspace we are in.
	if (_atomTable)
	{
		AtomSpace* as = _atomTable->getAtomSpace();
		return as->addAtom(result);
	}

	return result;
}

// ===========================================================

/// execute() -- Execute the expression, returning a number
///
/// Similar to reduce(), above, except that this can only work
/// on fully grounded (closed) sentences: after executation,
/// everything must be a number, and there can be no variables
/// in sight.
static inline double get_double(AtomSpace *as, Handle h)
{
	// Recurse, and execute anything below...
	FunctionLinkPtr flp(FunctionLinkCast(h));
	if (flp)
		h = flp->execute(as);

	NumberNodePtr nnn(NumberNodeCast(h));
	if (nnn == NULL)
		throw RuntimeException(TRACE_INFO,
			  "Expecting a NumberNode, got %s",
		     classserver().getTypeName(h->getType()).c_str());

	return nnn->getValue();
}

Handle FoldLink::execute(AtomSpace* as) const
{
	double sum = knil;
	for (Handle h: _outgoing)
	{
		sum = kons(sum, get_double(as, h));
	}

	if (as) return as->addAtom(createNumberNode(sum));
	return Handle(createNumberNode(sum));
}
<|endoftext|>